Так что я подозреваю, что если бы std :: initializer_list имел конструктор, который есть в классе Test, первый фрагмент кода скомпилировал бы
Это предполагает, что "равномерная инициализация" на самом деле равномерная , что всегда является опасным предположением.
initializer_list
имеет особые правила построения из списка фигурных скобок. Если вы примените braced-init-list к initializer_list<T>
, то включится [dcl.init.list] /3.5, который говорит идти «ниже», пропуская оставшиеся подпункты. А «внизу» говорит :
Объект типа std::initializer_list<E>
создается из списка инициализатора так, как если бы реализация генерировала и материализовала значение типа «массив из N
const E
», где N
- количество элементов в инициализаторе. список.
Итак, вы создаете initializer_list<int>
из одного элемента , который сам по себе является фигурным списком инициализации. Этот braced-init-list теперь применяется к E
, то есть int
. А поскольку в этом списке более одной записи, это не сработает.
Поскольку в подпункте 3.5 явно пропущены все остальные подпункты в этом разделе, не имеет значения , если этот внутренний фигурный список инициализации может создать initializer_list<int>
. Компилятор никогда не проверяет это, потому что проверка для этого была в 3.6 , которая была пропущена.
Для записи, initializer_list
имеет (по умолчанию) конструкторы копирования / перемещения и операторы присваивания.