Инициализация фигурных скобок без какого-либо значения
Можно ли написать что-то подобное
typedef unsigned long DWORD;
DWORD nBytesRead = {};
Будет ли эта переменная содержать 0 после этого выражения?
2 ответа
Да, это законно. Стандарт гласит (5.17.9):
В правой части присвоения скаляру может появиться фигурный список инициализации, и в этом случае список инициализатора должен содержать не более одного элемента. Значение x={v}, где T - это скалярный тип выражения x, означает x=T(v), за исключением того, что сужающее преобразование ( 8.5.4) не допускается. Значение x={} есть x=T()
Да, все в порядке, и вам гарантировано, что nBytesRead
будет содержать значение ноль. Вы инициализируете копию nBytesRead
с пустым списком инициализаторов, что для не-классового типа означает, что вы инициализируете его нулями. Нулевая инициализация означает именно то, что вы думаете, что это значит.
То, что вы делаете, называется list-copy-initialization. Из [dcl.init]:
Инициализация, которая происходит в
=
форма скобки-или-равно-инициализатора или [...] называется копией-инициализацией.
Из [dcl.init.list]:
Инициализация списка - это инициализация объекта или ссылки из списка фигурных скобок. Такой инициализатор называется списком инициализаторов, а разделенные запятыми пункты инициализатора списка называются элементами списка инициализаторов. Список инициализатора может быть пустым. Инициализация списка может происходить в контексте прямой инициализации или инициализации копирования; инициализация списка в контексте прямой инициализации называется прямой инициализацией списка, а инициализация списка в контексте инициализации копирования называется инициализацией копирования списка.
Куда:
Инициализация списка объекта или ссылки типа
T
определяется следующим образом:
- Если T является типом класса и [...]
- В противном случае, если T является массивом символов и [...]
- В противном случае, если T является агрегатом, [...]
- В противном случае, если список инициализаторов не имеет элементов и T является типом класса [...]
- В противном случае, если T является специализацией std::initializer_list, [...]
- В противном случае, если T является типом класса, [...]
- В противном случае, если список инициализаторов имеет один элемент [...]
- В противном случае, если T является ссылочным типом, [...]
- В противном случае, если в списке инициализатора нет элементов, объект инициализируется значением.
Инициализация значения для неклассового типа означает [dcl.init]:
Инициализировать значение объекта типа
T
средства:
- если T является (возможно, cv-квалифицированным) типом класса без конструктора по умолчанию [...]
- если T является (возможно, cv-квалифицированным) типом класса без предоставленного пользователем или удаленного конструктора по умолчанию [...]
- если T является типом массива, [...]
- иначе объект инициализируется нулями.
Нулевая инициализация означает, [dcl.init]:
Для инициализации нуля объекта или ссылки типа
T
средства:
- если T скалярного типа (3.9), объект инициализируется значением, полученным путем преобразования целочисленного литерала 0 (ноль) вT