花括号初始化没有任何值

6
这样写可以吗?
typedef unsigned long DWORD;
DWORD nBytesRead = {};

这个表达式执行后,这个变量会包含0吗?

2
什么阻止你尝试一下呢? - 463035818_is_not_a_number
2
@tobi303 我想知道标准对这种情况的规定,而不是某个具体实现。 - FrozenHeart
如果你想知道“根据标准,这个变量在表达式之后是否应该包含0”,那么你可能需要询问,因为在许多情况下编译器比标准规定更友好。 - 463035818_is_not_a_number
是的,这很重要,因为它允许您编写在其默认构造函数中不执行任何操作(以便可以将它们廉价地放入数组)但在必要时也可以进行零初始化的类型。 - TemplateRex
2个回答

7
是的,这样做没有问题,并且您可以保证nBytesRead的值为零。您正在使用空初始化列表对nBytesRead进行复制初始化,对于非类类型来说,这意味着您正在进行零初始化。零初始化的含义正是您所想象的那样。
您所做的这种初始化称为列表复制初始化。来自[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所得的值

6

是的,这是合法的。标准规定(5.17.9):

一个大括号初始化列表可以出现在将标量赋值的右侧,此时初始化列表最多只能有一个元素。当 T 是表达式 x 的标量类型时,x={v} 的含义是 x=T(v),但不允许收缩转换(8.5.4)。x={} 的含义是 x=T()


3
这不是引用正确的部分。赋值不等同于初始化。 - cpplearner
1
这既不是赋值,也没有回答nBytesRead会有什么值。-1。 - Barry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接