Агрегатная инициализация std::array подобъектов с вложенными списками инициализаторов

Каков правильный способ инициализации агрегатного типа (например, std::array) и его подобъектов с помощью вложенных списков инициализаторов в фигурных скобках? Я не хочу напрямую вызывать конструкторы подтипов.

Это повторяющаяся проблема, и я всегда удивляюсь, что приведенный ниже код не работает, поскольку тип элементов указан, поэтому компилятор может вывести правильный конструктор.

Обратите внимание, что тип примера 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>'

person plasmacel    schedule 18.10.2016    source источник


Ответы (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} становится избыточным предложением.

person songyuanyao    schedule 18.10.2016
comment
Можно поподробнее, зачем это нужно? Я думал, что при удалении скобок дополнительная скобка не нужна. - person plasmacel; 18.10.2016
comment
@plasmacel std::array<A, 2> arr{{ 0, 1, 2, 3 }, { 4, 5, 6, 7 }}; нарушает правило исключения фигурных скобок, инициализатор имеет 2 предложения, что не соответствует количеству элементов соответствующего подагрегата, - person songyuanyao; 18.10.2016