Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

arrays

c++11

In order to initialize a std::array 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 std::array and the the other for the inner c-style array).

My question: Why, by standard, std::array 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};

Edit:

This information is from http://en.cppreference.com/w/cpp/container/array. 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)

like image 440
Humam Helfawi Avatar asked Oct 25 '16 11:10

Humam Helfawi


People also ask

Does std :: array initialize?

std::array contains a built-in array, which can be initialized via an initializer list, which is what the inner set is. The outer set is for aggregate initialization.

Does initializer list call constructor?

An initialization list can be used to explicitly call a constructor that takes arguments for a data member that is an object of another class (see the employee constructor example above). In a derived class constructor, an initialization list can be used to explicitly call a base class constructor that takes arguments.

What happens if an array initializer has more values than the size of the array?

An initializer-list is ill-formed if the number of initializer-clauses exceeds the number of members or elements to initialize.

What is a constructor initializer?

Constructor is a special non-static member function of a class that is used to initialize objects of its class type. In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual bases and non-static data members.


1 Answers

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

§23.3.2.1 [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}
like image 120
krzaq Avatar answered Oct 20 '22 04:10

krzaq