Why is the behavior of C ++ initializer_list for std :: vector and std :: array different?

the code:

std::vector<int> x{1,2,3,4}; std::array<int, 4> y{{1,2,3,4}}; 

Why do I need double curly braces for std :: array?

+60
c ++ c ++ 11 stl
Jul 09 '12 at 17:30
source share
2 answers

std::array<T, N> is a collection: it does not have any user-declared constructors, even one of them does not accept std::initializer_list . Initialization using curly braces is performed using aggregate initialization, a C ++ function that was inherited from C.

In the old style, aggregate initialization uses = :

 std::array<int, 4> y = { { 1, 2, 3, 4 } }; 

In this old aggregate initialization style, extra curly braces can be undone, so this is equivalent to:

 std::array<int, 4> y = { 1, 2, 3, 4 }; 

However, these additional curly braces can only be canceled "in the declaration of the form T x = { a }; " (C ++ 11 §8.5.1 / 11), that is, when the old style = . This rule, which allows alignment of shapes, is not used to directly initialize a list. The footnote here says: "Brackets cannot be deleted with other uses of list initialization."

There is a bug report regarding this limitation: defect CWG # 1270 . If the adopted proposed resolution is adopted, the exclusion of curly braces will be allowed for other forms of list initialization, and the following will be well-formed:

 std::array<int, 4> y{ 1, 2, 3, 4 }; 

(Ville Voutilainen hat tip for finding a bug report.)

+55
Jul 09 2018-12-12T00:
source share

Because std::vector offers a constructor that takes std::initializer_list<T> , while std::array has no constructors, and list {1, 2, 3, 4} is not really interpreted as std::initializer_list , but aggregate initialization for the internal C-style std::array (the one where the second set of curly braces comes from: One for std::array , one for the internal array of C-style elements).

+23
Jul 09 '12 at 17:33
source share



All Articles