7

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)

Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160

1 Answers1

6

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}
krzaq
  • 16,240
  • 4
  • 46
  • 61
  • Thanks... in other words, it can not contain user-defined constructor so they solve the problem in C++ 14 by brace illusion.. right? – Humam Helfawi Oct 25 '16 at 11:32
  • @HumamHelfawi yes, they changed the rules for all aggregates: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1270 – krzaq Oct 25 '16 at 11:33
  • 1
    The answer could be completed by §8.5.1 [dcl.init.agr] item 12 (in specification draft N4296 and probably the same item in earlier versions): "Braces can be elided in an initializer-list as follows..." this specification item explains why one can removes the inner brace when initializing an aggregate. – Oliv Oct 25 '16 at 11:35
  • @Oliv edited, thanks. – krzaq Oct 25 '16 at 11:46
  • @LightnessRacesinOrbit you don't even see the sleight of hand, and your braces are gone! – krzaq Oct 25 '16 at 11:51
  • It's amazing! The Fantastic Illusory Braces! Roll up, roll up... – Lightness Races in Orbit Oct 25 '16 at 11:53