From: Dragan Milenkovic on
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
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! ]