Copy-initialization of std::array with braces (valid or ill-formed?)

81 views
Skip to first unread message

Vincent Reverdy

unread,
Apr 18, 2014, 1:13:24 PM4/18/14
to std-dis...@isocpp.org
Hello.

In this answer: http://stackoverflow.com/questions/20519992/array-declaration-and-initialization-in-c11
the author of the answer says:
-----------------------------------------------------------------
std::array<int, 3> arr6 = std::array<int, 3>({1, 2, 3});
std::array<int, 3> arr7 = std::array<int, 3>({{1, 2, 3}});

These are examples of copy-initialization; similar to 1 and 2, there's a temporary created (through the expression std::array<int, 3>({1, 2, 3})) and this temporary is copied/moved to the named destination variable. This can be elided as well. As far as I know, an implementation could write an explicit array(array const&) = default; constructor and not violate the Standard; this would make those examples ill-formed.

-----------------------------------------------------------------
It compiles well under g++ 4.8.0, and I am not sure why defining explicit array(array const&) = default; would make the example ill-formed. But if the statement of the author is correct, it seems strange to me whether such a syntax would be considered as valid or not valid is compiler-dependent.

Any thoughts about this example ?

Thank you very much.

Vincent

David Krauss

unread,
Apr 18, 2014, 1:45:49 PM4/18/14
to std-dis...@isocpp.org
On 2014–04–19, at 1:13 AM, Vincent Reverdy <vinc...@gmail.com> wrote:

Hello.

In this answer: http://stackoverflow.com/questions/20519992/array-declaration-and-initialization-in-c11
the author of the answer says:
-----------------------------------------------------------------
std::array<int, 3> arr6 = std::array<int, 3>({1, 2, 3});
std::array<int, 3> arr7 = std::array<int, 3>({{1, 2, 3}});

These are examples of copy-initialization; similar to 1 and 2, there's a temporary created (through the expression std::array<int, 3>({1, 2, 3})) and this temporary is copied/moved to the named destination variable.


There are two copies: The argument {1,2,3} initializes a temporary to complete the function call conversion notation. Then another copy is implied copy-initialization per the = sign.

This can be elided as well. As far as I know, an implementation could write an explicit array(array const&) = default; constructor and not violate the Standard; this would make those examples ill-formed.

Yes, because such a declaration (as long as it’s all inside the class-specifier) doesn’t disqualify array as an aggregate.

-----------------------------------------------------------------
It compiles well under g++ 4.8.0, and I am not sure why defining explicit array(array const&) = default; would make the example ill-formed. But if the statement of the author is correct, it seems strange to me whether such a syntax would be considered as valid or not valid is compiler-dependent.

explicit constructors are disqualified from copy-list-initialization, which is the form of initialization used for initializer list arguments to function calls.

It sounds like a GCC bug.

David Krauss

unread,
Apr 18, 2014, 2:35:24 PM4/18/14
to std-dis...@isocpp.org

On 2014–04–19, at 1:45 AM, David Krauss <pot...@gmail.com> wrote:

explicit constructors are disqualified from copy-list-initialization, which is the form of initialization used for initializer list arguments to function calls.

Ah, explicit constructors are disqualified from all copy-initialization. If std::array had an explicit copy constructor, it could not be passed by value and it would not be CopyConstructible. This would also violate the container requirement "X u = a;” so it would be nonconforming (not to mention perverse).

Reply all
Reply to author
Forward
0 new messages