Инициализация T v{}

Я читаю стандарт С++ 11, но не могу понять,

T x{};

инициализируется значением или инициализируется по умолчанию (автоматическое сохранение). В нем действительно четко сказано, что:

10 Объект, инициализатором которого является пустой набор круглых скобок, т. е. (), должен быть инициализирован значением.

И это

11 Если для объекта не указан инициализатор, объект инициализируется по умолчанию;

Но все, что я могу найти о T x{};, это то, что:

Инициализация, происходящая в формах T x(a); Т х {а}; а также в новых выражениях (5.3.4), выражениях static_cast (5.2.9), преобразованиях типов функциональной нотации (5.2.3) и инициализаторах базы и члена (12.6.2) называется прямой инициализацией.

а также

Если инициализатор представляет собой (не заключенный в скобки) список-инициализации в фигурных скобках, объект или ссылка инициализируются списком (8.5.4).

Я новичок в погружении на уровень чтения стандартов. Может ли кто-нибудь указать мне в правильном направлении?


person zac    schedule 21.09.2014    source источник


Ответы (2)


Это действительно отражено в вашей цитате:

Если инициализатором является (не заключенный в скобки) список инициализации в фигурных скобках, объект или ссылка инициализируется списком (8.5.4).

Переходим к 8.5.4 Инициализация списка. Здесь я перефразировал/опустил некоторые моменты, не относящиеся к случаю T x{}:

Список-инициализация объекта или ссылки типа T определяется следующим образом:

  • Если T является агрегатом, выполняется агрегатная инициализация (8.5.1).
  • В противном случае, если в списке инициализаторов нет элементов и T является типом класса с конструктором по умолчанию, объект инициализируется значением.
  • В противном случае, если T является специализацией std::initializer_list<E> [...]
  • В противном случае [если список не пуст и соответствует конструктору]
  • В противном случае [если список состоит из одного элемента]
  • В противном случае [если T является ссылочным типом]
  • В противном случае, если в списке инициализаторов нет элементов, объект инициализируется значением.
  • В противном случае программа некорректна.

Первый пункт, агрегатная инициализация, также был в C++03; в этом случае T x{}; совпадает с T x = {};.

Во-вторых, T — это тип класса с конструктором по умолчанию, он инициализирован значением, что означает вызов конструктора по умолчанию.

Если T является типом-примитивом, то применяется предпоследняя точка, и он снова инициализируется значением.

Возвращаясь к случаю агрегированной инициализации, в версии 8.5.1/7:

Если в списке меньше предложений-инициализаторов, чем элементов в совокупности, то каждый элемент, не инициализированный явно, должен быть инициализирован из его инициализатора-или-равно-скобки или, если инициализатора-или-равно-скобки нет, из пустого списка инициализаторов (8.5.4).

Инициализатор скобок или равенства относится к инициализатору, указанному в определении класса. Если этого нет, то он инициализируется, как если бы элемент был инициализирован с помощью {} (таким образом, эта логика рекурсивно применяется для каждого члена агрегата).

Например,

struct T
{
     int a;
};

тогда T x {}; приводит к инициализации a, как если бы это был int a{}; , что является инициализацией значения, поскольку int является примитивным типом.

person M.M    schedule 21.09.2014
comment
Спасибо, что нашли это - я прочитал list-initialization и подумал, что это подразумевает использование › 1 элемента. - person zac; 22.09.2014
comment
Глядя на это, я испытываю одновременно благоговение и страх перед C++. - person Vilx-; 24.09.2014
comment
@Vilx Хе, да. Есть много вещей, которые нужно знать. Инициализация списка для неагрегатов была добавлена ​​​​в С++ 11... она решает некоторые проблемы (поиск наиболее неприятных синтаксических анализов), но добавляет несколько новых странных угловых случаев. - person M.M; 24.09.2014

Хотя Мэтт Макнабб уже рассказал об этом, я добавлю, что если у вас возникли проблемы с навигацией по стандарту, не помешает проверить cppreference. . В их разделе, посвященном инициализации списка, все довольно подробно описано.

По сути, как говорится в вашей стандартной цитате, T x{}; относится к:

инициализация именованной переменной заключенным в фигурные скобки списком выражений или вложенными списками (braced-init-list).

А также:

Эффекты инициализации списка объекта типа T:

  • Если список инициализации в фигурных скобках пуст и T является типом класса с конструктором по умолчанию, выполняется инициализация значения.

[...]

  • В противном случае, если список инициализации в фигурных скобках не содержит элементов, T инициализируется значением.
person Community    schedule 21.09.2014