Niels Dekker - address until 2010-10-10 wrote:
snipped...
Edward Diener wrote:
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.
I do not really understand the need for the 'explicit_copy_t' in your possibilities. I favor 2), although 1) is fine also. I see little reason for the templated constructor in practical use, especially since the current usage of value_initialized does not consider conversions to and from the T type in any of its functionality.