Would the removal of "const" in dcl.init.list#5 cause havoc in the standard?

117 Views Asked by At

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 N const 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.

1

There are 1 best solutions below

0
user17732522 On

Removing const there wouldn't make your code well-formed. The reference_type of the iterator produced by std::initializer_list::begin is still a const lvalue reference instead of a rvalue reference as you would need here.

Removing const there 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

constexpr std::initializer_list<T> i = {1,2,3};
constexpr T j = *i.begin();

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 be const-qualified to avoid contradictions.