Of course, technically speaking, a constructor could be added to value_initialized<T> that accepts a T argument, and copies its value. But if so, value_initialized<T> would no longer guarantee to always deliver value-initialized objects. Wouldn't that be a drawback?
Edward Diener wrote:
I don't see it as a big drawback but perhaps my viewpoint is limited to what I feel I need.
Maybe it's not a big drawback. It's just something we need to consider, before we can (possibly) resolve your issue. (I'm saying "we" because I also got involved with value_initialized<T>, but the utility is from Fernando Cacciola, of course!)
The documentation would simply explain that when the constructor is not used, the guarantee holds, but when the constructor is used the object is no longer value initialized but constructed passing the value to the object type's constructor.
Certainly, the new feature should be well documented.
You could even provide the constructor only for top-level const T ( through the 'Structure Selection' technique as outlined in section 9.4 of the "C++ Template Metaprogramming Book" )
I think it's preferable to have a solution that treats const T and non-const T alike.
I like one-off situations as little as the next programmer, so if there is a better general solution it should be pursued.
Right :-)
Please have a look: https://svn.boost.org/trac/boost/ticket/2548
I do not see how this fixes the situation I outlined in my original OP.
Indeed, it does not. I just mentioned it because you might be interested, as it's also about const-ness and value_initialized.
I did design a template class I am coding to use value_initialized and afterward, when I was testing it, realized that when a const type gets used there is no way of setting the value_initialized value to a non-value_initialized value either during the construction of the object or subsequently. Since my template class is meant to be used by end-users, and I don't want to control the constness of the type passed as a template parameter, value_initialized can't be used by me as it currently exists.
I think your case is clear. Do you have a proposed resolution? :-) I guess we'd need to add an extra constructor that would copy from T to value_initialized<T>, right? I'm not yet entirely sure about its signature... IMO, all of them have their pro's and cons. For example: [1] value_initialized(const T&); [2] explicit value_initialized(const T&); [3] value_initialized(const T&, explicit_copy_t); [4] explicit template <class U> value_initialized(const U&); [5] template <class U> value_initialized(const U&, explicit_copy_t); I think each of them would be good enough to fix your issue, right? Option [1] is most straight forward. It allows implicit conversion from T to value_initialized<T>, which doesn't seem unreasonable. Still people might find such implicit conversion scary, and prefer to add an explicit keyword (option [2]). But there isn't much difference between [1] and [2] in your use case, having a value_initialized<T> as data member. So instead, an extra "dummy" parameter could be added, to avoid accidental copying, and to make such copying more "explicit". Like in option [3], assuming explicit_copy_t is an empty struct, struct explicit_copy_t {}. Option [4] and [5] are more generic, allowing conversion from anything that is convertible to T. Kind regards, Niels -- Niels Dekker http://www.xs4all.nl/~nd/dekkerware Scientific programmer at LKEB, Leiden University Medical Center