std::array<std::vector<int>, 2>
- это эффективно
struct array {
std::vector<int> elems[2];
};
elems
- это субагрегат, просто отлично.Проблема в том, что согласно правилам языка, если инициализатор начинается с {
, всегда предполагается, что вы не выбрасываете скобки;вместо этого {1, 2}
берется в качестве инициализатора всего подагрегата elems
, пытаясь инициализировать свой первый элемент с 1
, а второй элемент с 2
(это, очевидно, неверно - вы не можете преобразовать целое число вvector
- но не влияет на интерпретацию), и {3, 4}
считается инициализатором вещи после elems
- и поскольку такой вещи нет, это еще одна ошибка.
Инициализация первойэлемент с чем-то, что не является braced-init-list достаточно для запуска скобки:
std::array<std::vector<int>, 2> v = { std::vector<int>{1,2}, {3,4} };
Обратите внимание, что с точки зрения спецификации библиотека не гарантирует инициализациюstd::array<T, N>
из чего-либо, кроме std::array<T, N>
или списка «до N элементов, типы которых могут быть преобразованы в T
».Это, в частности, исключает braced-init-list s, потому что они не имеют типа, и фактически также запрещает «двойные скобки», потому что это просто особый случай наличия одного элемента, который является braced-init-список .
Это область, в которой нам, возможно, лучше было бы указать ее с помощью кода.Основные языковые правила не поддаются простой спецификации в словах, а детали реализации будут просачиваться - и уже сделали это.