#c #initialization #initializer-list #initializer #stdarray
#c #инициализация #инициализатор-список #инициализатор #stdarray
Вопрос:
Каков правильный способ инициализации агрегированного типа (например, std::array
) и его подобъектов с вложенными списками инициализаторов? Я не хочу напрямую вызывать конструкторы подтипа (ов).
Это повторяющаяся проблема, и я всегда удивляюсь, что приведенный ниже код не работает, поскольку указан тип элементов, поэтому компилятор может вывести правильный конструктор.
Обратите внимание, что тип example A
не обязательно должен быть агрегированным (но, конечно, он должен поддерживать привязанные списки инициализаторов).
#include <array>
struct A
{
int values[4];
};
int main()
{
std::array<A, 2> arr{{ 0, 1, 2, 3 }, { 4, 5, 6, 7 }};
// Works only if A is an aggregate, also looks confusing, I don't want to do this
//std::array<A, 2> arr{ 0, 1, 2, 3, 4, 5, 6, 7 };
// I don't want to do this neither
//std::array<A, 2> arr{A{ 0, 1, 2, 3 }, A{ 4, 5, 6, 7 }};
return 0;
}
Но все, что я получаю, это ошибка
error: too many initializers for 'std::array<A, 2ul>'
Ответ №1:
Вы могли бы добавить фигурные скобки вокруг инициализации подобъекта, например
std::array<A, 2> arr{{{ 0, 1, 2, 3 }, { 4, 5, 6, 7 }}};
std::array<A, 2> arr{{ 0, 1, 2, 3 }, { 4, 5, 6, 7 }};
не работает, потому что для исключения фигурных скобок,
фигурные скобки вокруг вложенных списков инициализаторов могут быть опущены (опущены), и в этом случае для инициализации каждого элемента или элемента соответствующего подгруппы используется столько предложений инициализатора, сколько необходимо, а последующие предложения инициализатора используются для инициализации следующих членов объекта.
Обратите внимание, что 1-е предложение инициализатора { 0, 1, 2, 3 }
может использоваться для инициализации всего внутреннего массива std::array
(остальные элементы будут инициализированы нулем). Затем { 4, 5, 6, 7}
становится избыточным предложением.
Комментарии:
1. Можете ли вы пояснить, почему это требуется? Я думал, что при удалении фигурных скобок дополнительная фигурная скобка не нужна.
2. @plasmacel
std::array<A, 2> arr{{ 0, 1, 2, 3 }, { 4, 5, 6, 7 }};
нарушает правило исключения скобок, инициализатор имеет 2 предложения, что не соответствует количеству элементов соответствующего подгруппы,