6

写这样的东西可以吗

typedef unsigned long DWORD;
DWORD nBytesRead = {};

这个变量会在这个表达式之后包含 0 吗?

4

2 回答 2

7

是的,没关系,您可以保证它nBytesRead包含零值。您正在nBytesRead使用空的初始化程序列表进行复制初始化,对于非类类型,这意味着您正在对其进行零初始化。零初始化正是您认为的意思。


您正在做的事情称为list-copy-initialization。来自 [dcl.init]:

以大括号或相等初始化器=或 [...] 的形式发生的初始化称为复制初始化

来自 [dcl.init.list]:

列表初始化是从一个花括号初始化列表初始化一个对象或引用。这样的初始化器称为初始化器列表,列表中以逗号分隔的初始化器子句称为初始化器列表的元素。初始化列表可能为空。列表初始化可以发生在直接初始化或复制初始化上下文中;直接初始化上下文中的列表初始化称为直接列表初始化,复制初始化上下文中的列表初始化称为复制列表初始化

在哪里:

对象或类型引用的列表初始化T定义如下:
— 如果 T 是类类型并且 [...]
— 否则,如果 T 是字符数组并且 [...]
— 否则,如果 T 是aggregate, [...]
— 否则,如果初始化器列表没有元素并且 T 是类类型 [...]
— 否则,如果 T 是 std::initializer_list 的特化,[...]
— 否则,如果 T 是类类型,[...]
— 否则,如果初始化列表有单个元素 [...]
— 否则,如果 T 是引用类型,[...]
— 否则,如果初始化列表没有元素,对象是值初始化的

对于非类类型,值初始化意味着 [dcl.init]:

对类型对象进行值初始化T意味着:
— 如果 T 是(可能是 cv 限定的)类类型,没有默认构造函数 [...]
— 如果 T 是(可能是 cv 限定的)类类型,没有用户-提供或删除的默认构造函数 [...]
— 如果 T 是数组类型,[...]
否则,对象被零初始化。

零初始化意味着,[dcl.init]:

对类型的对象或引用进行零初始化T意味着:
— 如果 T 是标量类型 (3.9),则将对象初始化为通过将整型文字 0(零)转换为T

于 2015-09-18T12:33:52.463 回答
6

是的,这是合法的。该标准说(5.17.9):

一个花括号初始化列表可能出现在一个标量赋值的右侧,在这种情况下,初始化列表最多只能有一个元素。x={v} 的含义,其中 T 是表达式 x 的标量类型,是 x=T(v) 的含义,除了不允许缩小转换 (8.5.4)。x={} 的含义是 x=T()

于 2015-09-18T09:44:55.617 回答