Инициализация вложенных агрегатов имеет более или менее удивительное поведение, которое вы не добавляете для соответствия вложенным {
/ }
.
Например, это , как вы инициализируете std::array<std::array<int, 2>, 2>
:
std::array<std::array<int, 2>, 2> arr = { 1, 1, 2, 2 };
Выполнение { {1, 1}, {2, 2} }
не не работает!
Аналогично, для агрегатной инициализации в вашем случае не потребуется вложенный {
/ }
с уже выполненным CTAD (ну, с заданным параметром шаблона):
constexpr static As<2> as{"a","b", "1","2"}; // Ok!
Зная это, мы можем просто добавить следующее руководство по выводам:
template<class ... Ts>
As(Ts...) -> As<(sizeof...(Ts) + 1)/2>;
Это выбирает N
как «половину количества аргументов». И действительно, теперь вы можете инициализировать так:
constexpr static As as{"a","b", "1","2"}; // Deduces N = 2.
Демо: https://godbolt.org/z/oznEwl
Да, это теряет возможность структурировать ввод с помощью {
/ }
для лучшей читаемости, но я виню здесь инициализацию агрегата (см. Пример с вложенным массивом выше).