Ответ 1
Это действительно покрывается вашей цитатой:
Если инициализатор представляет собой (не заключенный в скобки) бит-init-list, объект или ссылка инициализируется по списку (8.5.4).
Переход до 8.5.4 Инициализация списка. Здесь я перефразировал/пропустил некоторые моменты, которые не относятся к случаю T x{}
:
Список-инициализация объекта или ссылки типа T определяется следующим образом:
- Если T является агрегатом, выполняется агрегатная инициализация (8.5.1).
- В противном случае, если в списке инициализаторов нет элементов, а T - тип класса с конструктором по умолчанию, объект инициализируется значением
- В противном случае, если
T
является специализациейstd::initializer_list<E>
[...]- В противном случае [если список не пуст и соответствует конструктору]
- В противном случае, [если список имеет один элемент]
- В противном случае, если
T
является ссылочным типом]- В противном случае, если в списке инициализаторов нет элементов, объект инициализируется значением.
- В противном случае программа плохо сформирована.
Первая точка, агрегатная инициализация была также в С++ 03; в этом случае T x{};
совпадает с T x = {};
.
Для второй точки "T - тип класса с конструктором по умолчанию", это инициализируется значением, что означает вызов конструктора по умолчанию.
Если T
является примитивным типом, то применяется вторая-последняя точка и снова инициализируется инициализацией значения.
Возвращаясь к суммарному случаю инициализации, в 8.5.1/7 есть:
Если в списке меньше предложений-инициализаторов, чем в совокупности, то каждый член, явно не инициализированный, должен быть инициализирован из своего элемента с равным-равным-инициализатором или, если нет скобок или равно -initializer, из пустого списка инициализаторов (8.5.4).
Инициализатор, основанный на скобках или равных, относится к инициализатору, предоставленному встроенным в определение класса. Если этого нет, то он инициализируется так, как если бы элемент был инициализирован с помощью {}
(так что эта логика рекурсивно применяется для каждого элемента агрегата).
Например,
struct T
{
int a;
};
то T x {};
приводит к инициализации a
, как если бы он был int a{};
, который является инициализацией значения, так как int
является примитивным типом.