код:
std::vector<int> x{1,2,3,4};
std::array<int, 4> y{{1,2,3,4}};
Зачем мне нужны двойные фигурные скобки для std:: array?
код:
std::vector<int> x{1,2,3,4};
std::array<int, 4> y{{1,2,3,4}};
Зачем мне нужны двойные фигурные скобки для std:: array?
std::array<T, N>
- это совокупность: у него нет никаких объявленных пользователем конструкторов, даже один из них не принимает std::initializer_list
. Инициализация с использованием фигурных скобок выполняется с использованием агрегатной инициализации, функции С++, которая была унаследована от C.
В "старом стиле" инициализации агрегата используется =
:
std::array<int, 4> y = { { 1, 2, 3, 4 } };
В этом старом стиле инициализации агрегата могут быть отменены дополнительные фигурные скобки, поэтому это эквивалентно:
std::array<int, 4> y = { 1, 2, 3, 4 };
Однако эти дополнительные фигурные скобки могут быть отменены только "в объявлении формы T x = { a };
" (С++ 11 §8.5.1/11), то есть когда используется старый стиль =
. Это правило, разрешающее выравнивание фигур, не применяется для прямой инициализации списка. В сноске здесь говорится: "Скобки не могут быть удалены при других использованиях инициализации списка".
Существует отчет о дефекте относительно этого ограничения: дефект CWG # 1270. Если принятая предлагаемая резолюция будет принята, для других форм инициализации списка будет разрешено исключение фигурных скобок, и следующее будет хорошо сформировано:
std::array<int, 4> y{ 1, 2, 3, 4 };
(подсказка о шляпе Ville Voutilainen для поиска отчета о дефекте.)
Потому что std::vector
предлагает конструктор, который принимает std::initializer_list<T>
, тогда как std::array
не имеет конструкторов, а list {1, 2, 3, 4}
, на самом деле не интерпретируется как std::initializer_list
, но агрегатная инициализация для внутренний массив C-стиля std::array
(тот, где второй набор фигурных скобок происходит от: One для std::array
, один для внутреннего массива элементов C-стиля).