The problem
Consider the following type aliasing:
template<std::size_t N>
using square_matrix = std::array<
std::array<int, N>,
N>;
Intuitively, one may try to use brace-initialization as follows:
square_matrix<3> m = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
Just to find out that the above does not compile. Instead, the correct initiliazation reads:
square_matrix<3> m = {{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}};
The rationale
So, what's the reason for the extra inner {...}
?
The answer lies in the definition of std::array
:
std::array
is an aggregate type with the same semantics as a struct holding a C-style arrayT[N]
as its only non-static data member.
Remember that aggregates do not have a user-declared constructor. The only why to initialize an aggregator is to use brace-initialization. That is:
AggregateType a = { // start initializing a
... // initialize a's members
}; // stop initializing a
The first (and only) data member of std::array
is an array of size N
, and this member is directly initialized with initializer.
The extra braces are therefore needed for the internal array which is directly being initialized.
The case of 1-dimension arrays
If this is the case, why can we omit the extra braces for 1-dimensional arrays? That is, why can we do the following?
std::array<int, 3> a = {1, 2, 3};
The reason is in Paragraph 8.5.1.11 of the C++ standard:
Braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the members of a subaggregate; it is erroneous for there to be more initializer-clauses than members. If, however, the initializer-list for a subaggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the members of the subaggregate; any remaining initializer-clauses are left to initialize the next member of the aggregate of which the current subaggregate is a member.
C++14
N3526 proposed to relax the rules for brace-initialization so as to allow the natural syntax introduced at the beginning. Unfortunately, it has been marked as NAD (not a defect).