
Hi People, OK, only seven months after Eduard's inital request I finally made the time to really look at it :) Jeffrey Hellrung wrote:
Niels Dekker - address until 2010-10-10 wrote:
Can anybody please have a look at the following feature request by Edward Diener? https://svn.boost.org/trac/boost/ticket/3472 He proposed to add an explicit constructor, value_initialized(T const&), to boost::value_initialized<T>. This constructor would copy the value of its argument to the object held by value_initialized<T>.
OK, so as Niels quite clearly figured out, what Eduard wanted was this wrapper to contain values either value or directrly initialized.
When such a constructor would be added, an object held by value_initialized<T> might no longer be value-initialized. Instead it might be direct-initialized.
Does anybody have any moral (?) objections against the idea that value_initialized<T> might hold a non-value-initialized object?
A reasonable objection would be that a new comer would rightly question: why is it called "value_" then, when in effect I'm direct-initializing it instead in
Indeed. this case here? Of course, a quick answer would be that the class guarantess value initialization only when there is none, logicaly, and that the name is really short for value_or_direct_initialized.
Personally I think it would be useful to allow the wrapped object to be direct-initialized. But I do think there's a small risk that the new explicit constructor might cause ambiguities in legacy user code.
Therefor I suggested adding an extra "tag" parameter to the new constructor, of a new type, boost::direct_initialized_t:
struct direct_initialized_t { }; value_initialized(T const&, direct_initialized_t)
Does anyone else also think that's a good idea? Or does anyone prefer the explicit value_initialized(T const&) constructor originally proposed by Edward?
I'm not religiously against the additional parameter, but I definitely wouldn't
I followed ALL of the MSVC bug reports, threads, even related CCW issues, and I fail to see how in OUR case here there could be any ambiguity? The MSVC (and GCC) bugs all boils down to a resolution mistake rooted on certain "constructors that copy" in the base class. These bugs are not about a mistaken ambiguity, which would turn a legal program into ill-formed, forcing the programmer to change it, but about a wrong selection, whose consequences are quite different.. so let's see: None of these bugs reported show up when the choices are (a) the copy constructor and (b) a **non-template** explicit constructor, as in our case. So, I don't see why would we have to expect that to happen here. But even if a compiler would get it wrong, as in those bugs, and called the wrong ctor, the net effect would nevertheless be the same in our very specific case (the worst that could happen is an extra temporary surely ellided anyway). On the other front, regarding Neil's other sources of ambiguity... well, honestly, if a user writes such code, I'm more than happy to put him out his missery by not letting him compile such a mounstrocity anymore :) Or can you come up with a less aritificial and contorted used case that could result in ambiguity? like it for no reason, and after all the analysis about what could effectively happen, I don't see any reason for complicating it. So I'd go for Eduard's patch.
See also the thread starting at: "Re: [boost] Transfer of Maintenance Rights (utility/value_init)" http://lists.boost.org/Archives/boost/2010/03/164125.php
Kind regards,
Niels
Is defining a new template class (e.g., value_or_direct_initialized<T>, or whatever) out of the question? Just a suggestion, and not confident it's a good one...
OTOH, there is a new angle here... Having said that I'm more than happy with an extended value_initialized<> that accepts direct initialization via a straightforward ctor, it *could* be argued that having both initialized and value_initialized makes sense all by itself. But let's see: I can imagine myself explaining that "initialize<T> m(v)" does direct-initialization, then that, OTOH, "initialized<T> m;" does value-initialization, since there is no explicit initialization in this case. Newcomers would say "OK, I follow". Then I would proceed and explain that, "value_initialized<T> m" is also doing value-initialization... What? why would I ever want to use that one then, having the other?? And then I would answer: hmmm, right, you don't. So the slipts ends up being just to prevent user code to break when we add the feature... Since I don't really see user code being broken here, this split makes no sense to me. What would have made sense is to have called this "initialized" to begin with, and feature it with direct-initialization super powers! But adding this *now* and leave its old ancestor for the elder? don't like it. So, let's just add the plain and simple explicit ctor :) [Neils, feel free to argue back :) Best -- Fernando Cacciola SciSoft Consulting, Founder http://www.scisoft-consulting.com