Как инициализировать объект std :: array & lt; std :: array & lt; T, 2 & gt ;, 2 & gt ;?

Я пытаюсь инициализировать объекты типа вещь:

template<typename T>
struct thing : std::array<std::array<T, 2>, 2>
{
};

thing<int> t1 {{ {1,2}, {3,4} }};

Я получил:

 error: no matching function for call to ‘thing<int>::thing(<brace-enclosed initializer list>)’
thing<int> t1 {{{1,2},{3,4}}};

То же самое с

thing<int> t0{{ 1, 2, 3, 4 }};

и несколько других вещей.

5

Решение

Если вы используете компилятор C ++ 17, вам не хватает только дополнительного набора скобок. Следующие компилирует:

thing<int> t1 { { { {1,2}, {3,4} } } };
//            | | | |- braces for inner array
//            | | |--- braces for outer array
//            | |----- braces for base sub object of thing
//            |------- braces for list initialization of thing

C ++ 17 модифицированный правила для агрегатов, разрешающие базовые классы, если они public и неvirtual,

От §11.6.1 / 1 [dcl.init.aggr]

совокупный это массив или класс с
(1.1)
не предоставлено пользователем, explicitили унаследованные конструкторы ([class.ctor]),
(1.2)
нет частных или защищенных нестатических членов данных ([class.access]),
(1.3)
нет виртуальных функций, и
(1.4)
нет виртуальных, частных или защищенных базовых классов ([class.mi]).

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

элементы из совокупности являются:
(2.1)
для массива элементы массива в порядке возрастания индекса или
(2.2)
для класса — прямые базовые классы в порядке объявления, за которыми следуют прямые нестатические члены данных ([class.mem]), которые не являются членами анонимного объединения, в порядке объявления.


C ++ 14 и более ранние, Вариант ответа следующий:

std::array является агрегатом, а инициализация, выполненная с использованием списка фигурных скобок-инициализации, является агрегатной инициализацией. Тем не мение, thing не является агрегатом, поскольку имеет базовый класс.

От §8.5.1 / 1 [dcl.init.aggr]

совокупный является массивом или классом (раздел 9) без предоставленных пользователем конструкторов (12.1), без закрытых или защищенных нестатических элементов данных (раздел 11), нет базовых классов (Пункт 10), и нет виртуальных функций (10.3).

Таким образом, агрегатная инициализация не будет работать. В зависимости от того, что вы пытаетесь сделать, вы либо хотите предоставить конструктор для thing это занимает std::array<std::array<T, 2>, 2> аргумент и инициализировать базовый подобъект

template<typename T>
struct thing : std::array<std::array<T, 2>, 2>
{
thing(std::array<std::array<T, 2>, 2> arr)
: std::array<std::array<T, 2>, 2>(arr)
{}
};
thing<int> t{ {{ {{1,2}}, {{3,4}} }} };

Или есть thing содержать std::array в качестве члена данных. Сейчас thing все еще совокупность.

template<typename T>
struct thing
{
std::array<std::array<T, 2>, 2> arr;
};
thing<int> t{ {{ {{1,2}}, {{3,4}} }} };

Если то, что вы пытаетесь сделать, это иметь thing быть псевдонимом для array<array<T,2>,2>, тогда вам не нужно ничего из вышеперечисленного. использование

template<typename T>
using thing = std::array<std::array<T, 2>, 2>;

thing<int> t{{ {{1,2}}, {{3,4}} }};
9

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector