Если вы используете компилятор C++ 17, вам не хватает дополнительного набора фигурных скобок. Следующий compiles:
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 modified правила для агрегатов, чтобы обеспечить базовые классы, до тех пор, пока они public
и не- virtual
.
От §11.6.1/1 [dcl.init.aggr]
совокупности представляет собой массив или класс с
(1.1) нет пользователем при условии, explicit
или наследоваться конструкторы ([class.ctor]),
(1.2) нет частных или защищенных нестатических элементов данных ([класс.access]),
(1.3) нет виртуальных функций, и
(1.4) нет виртуальных, закрытых или защищенных базовых классов ([class.mi]).
Базовые классы теперь считаются elements of the aggregate, и сами по себе могут быть инициализированы с помощью списка инициализацию,
В элементах из агрегата являются:
(2.1) для множества, элементы массива в порядке возрастания индекса, или
(2.2) для класса классов прямых базовых в декларации порядок, за которым следуют прямые нестатические члены данных ([class.mem]), которые не являются членами анонимного объединения, в порядке объявления.
C++ 14, а ранее, вариант ответа следующим образом:
std::array
представляет собой агрегат, и инициализация выполняется с помощью рамно-Init-списка является совокупной инициализация. Однако thing
не является агрегатом, потому что он имеет базовый класс.
От §8.5.1/1 [dcl.init.Aggr]
An агрегатного представляет собой массив или класс (пункт 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}} }};
Почему вы привязываетесь к наследованию от 2D-массива? – rashmatash
Если вы пытаетесь создать псевдоним массива, вам лучше сделать 'template using thing = std :: array , 2>;' –
Quentin