Boost logo

Boost Users :

Subject: Re: [Boost-users] [value_initialized] when T is const
From: Niels Dekker - address until 2010-10-10 (niels_address_until_2010-10-10_at_[hidden])
Date: 2009-09-20 09:24:23


>> 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

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net