Once more I wrote this code
std::vector<std::unique_ptr<Foo>> v{ std::make_unique<Foo>(), std::make_unique<Foo>() };
and then realized it's probably the fifth time. That line doesn't compile because of [dcl.init.list#5] (I have also already come across the relevant question here on StackOverflow¹):
An object of type
std::initializer_list<E>is constructed from an initializer list as if the implementation generated and materialized ([conv.rval]) a prvalue of type “array of Nconst E”
But it is so natural to expect that that line works, so my question is:
What would go wrong if one wanted to change that part of the standard in a way that makes that line of code work?
I'm not referring to changes to the standard of the form There's an exception to [dcl.init.list#5] for the case above, but to actually make take [dcl.init.list#5] and remove that const.
Existing code could break I guess, but would a lot more in the standard have to change to cope with the change I'm imagining?
(¹) And I'm also aware of this question, but the answer, I believe, doesn't really address the why.
Removing
constthere wouldn't make your code well-formed. Thereference_typeof the iterator produced bystd::initializer_list::beginis still aconstlvalue reference instead of a rvalue reference as you would need here.Removing
constthere will, I think, have no negative impact on any program behavior, however it would disallow the compiler from assuming that the elements of the initializer list won't be modified, i.e. it would prevent generally putting the array in read-only memory if the elements are constant-initialized.Correction for the answer above: I can think of one exception with regards to constant evaluation.
Currently it doesn't seem clear to me in the standard whether
is supposed to be well-formed for any given type
T. If it is supposed to be well-formed for some types, then certainly the backing array must beconst-qualified to avoid contradictions.