Prev: [C++03] Temporaries passed to constructor yield invalid member references
Next: Can const& functors be passed to functions efficiently (i.e. inlined, etc)?
From: Dragan Milenkovic on 30 May 2010 06:08 M Stefan wrote: > Hello. I am trying to write a class similar to this: > template <class StringT> > struct A > { > A (StringT const &str) : str(str) { } > StringT const &str; > }; > The problem is that the constructor allows passing temporaries, which > get destroyed as soon as the constructor finishes executing, not after > the object is destroyed. I don't think there is any help for you regarding references. Even if you somehow manage the impossible and limit invocation of the ctor to non-temporaries, the general problem with dangling references will persist. typedef A<std::string> AStr; std::shared_ptr<AStr> a; { std::string foo; a.reset(new AStr(foo)); } // dangle IMHO, it's best to clearly document the purpose and functionality of A. And now for other solutions. Clearly, the C++ way to do things is as in your "solution 3". You worry too much about performance. Don't tell me those strings are ~10MB. Think again about it, and if you really _need_ not to make copies, use std::shared_ptr as a member. { A(const std::shared_ptr<StringT> & str) : str(str) {} std::shared_ptr<StringT> str; } -- Dragan [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Martin B. on 30 May 2010 06:08
On 30.05.2010 01:39, M Stefan wrote: > Hello. I am trying to write a class similar to this: > template<class StringT> > struct A > { > A (StringT const&str) : str(str) { } > StringT const&str; > }; > The problem is that the constructor allows passing temporaries, which > get destroyed as soon as the constructor finishes executing, not after > the object is destroyed. > (....) > Discussing with some other people, we have come up with several > solutions, none of which fully satisfy me: > 1) Make the constructor take a non-const ref as opposed to a const > ref. (Why not: breaks const correctness) > 2) Add an additional level of indirection: (Why not: likely overhead) > struct A > { > boost::any str; > A () : str() {} > template<class StringT> void set_str(StringT const&s) { str = s; } > }; > 3) Make the constructor take a StringT as opposed to a reference (Why > not: overhead and additional memory) > > Please let me know if you have any better solutions to my problem. > Note that compatibility with C++03 is a must here, and performance is > kind of important. > Use a const pointer. Use it for the argument passing and if it's not too much hassle also use it for the member. Also see: http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/c561510cc7c53dc9 Bottom line for me is: Always use pointers for these parameters. Use a pointer member in "90%" of cases. br, Martin -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |