From: M Stefan on
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.
For instance, constructing the class: A<std::string> a("hello"); would
cause an implicit conversion from char const* to std::string const&,
and the converted temporary will be passed to the ctor. The reference
str of the class is then bound to this temporary, which gets destroyed
before the object, thus leaving the object with an invalid reference.
Then, I modified it so that no implicit conversions are allowed:
template <class StringT>
struct A
{
A (StringT const &str) : str(str) { }
template <class U> explicit A (U) { BOOST_STATIC_ASSERT(false); }
StringT const &str;
};
This fixes the problem with the conversion from char const* to
std::string const&, but still allows the following way of constructing
the class: A<std::string> a( (std::string("a")) );
This constructs A with a temporary which again gets destroyed before
the object, thus leaving an invalid ref behind.
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.

Best Regards,
Stefan

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]