Humam Helfawi Humam Helfawi - 11 months ago 50
C++ Question

Why std::array does not contain an initializer-list constructor

In order to initialize a

with some values, you need to use this approach:

std::array<int,3> an_array{{3,4,5}};

I am aware of the reason that we need two curly braces (one for
and the the other for the inner
c-style array

My question: Why, by standard,
does not contain an initializer-list constructor that directly initialize the inner
c-style array
? Is not more eyes-friendly to be initialized as:

std::array<int,3> an_array{3,4,5};


This information is from I thought my compiler is allowing the second version directly as non-standard extension. Now, I am not even sure what is the standard exactly about this case.

// construction uses aggregate initialization

std::array<int, 3> a1{ {1, 2, 3} };
// double-braces required in C++11 (not in C++14)

Answer Source

The standard defines std::array as follows (N3337 for C++11, but the quoted parts are identical in N4140):

§ [array.overview]/2

An array is an aggregate that can be initialized with the syntax

array<T, N> a = { initializer-list };

and an aggregate is defined as:

§8.5.1 [dcl.init.aggr]/1

An aggregate is an array or a class with no user-provided constructors, no private or protected non-static data members, no base classes, and no virtual functions.

So it cannot have a user-defined constructor, which an initializer_list one would be.

Additionally, C++11 defines brace elision only for the T x = { a } syntax:

§8.5.1 [dcl.init.aggr]/11

In a declaration of the form

T x = { a };

braces can be elided in an initializer-list as follows. [...]

whereas C++14 (N4140) lifts this requirement:

§8.5.1 [dcl.init.aggr]/11

Braces can be elided in an initializer-list as follows. [...]

So the following is perfectly valid C++14 and above:

std::array<int,3> an_array{3,4,5}