C++11 中带或不带花括号的初始化差异 [英] Initialization difference with or without Curly braces in C++11
问题描述
我们可以在 C++11 中通过两种方式初始化变量
We can initialize the variable in two ways in C++11
一个:
int abc = 7;
两个:
int abc {7};
这两种方法有什么区别?
What is the difference between these two methods?
编译器如何区别对待它们或执行这些代码的方式?
How compiler treats them differently or the way these codes are executed?
推荐答案
短版
通过{..}
初始化是列表初始化,禁止缩小转换.例如,如果 LLONG_MAX
是 long long int
的最大值,而您的 int
不能表示:
Short version
Initialization via {..}
is list-initialization, which prohibits narrowing conversions. For example, if LLONG_MAX
is the maximum value of an long long int
, and your int
cannot represent that:
int x = LLONG_MAX; // probably accepted with a warning
int x {LLONG_MAX}; // error
同样:
long long y = /*something*/;
int x = y; // accepted, maybe with a warning
int x {y}; // error
<小时>
加长版
表单的初始化
T x = a;
是复制初始化;任一形式的初始化
T x(a);
T x{a};
是直接初始化,[dcl.init]/15-16.
is direct-initialization, [dcl.init]/15-16.
[dcl.init]/14 然后说:
[dcl.init]/14 then says:
初始化的形式(使用括号或=
)通常无关紧要,但当初始化器或被初始化的实体具有类类型时,它就很重要;见下文.
The form of initialization (using parentheses or
=
) is generally insignificant, but does matter when the initializer or the entity being initialized has a class type; see below.
所以对于非类类型,初始化的形式 无关紧要.但是,这两种直接初始化是有区别的:
So for non-class types, the form of the initialization doesn't matter. However, there's a difference between these two direct-initializations:
T x(a); // 1
T x{a}; // 2
同样,在这两个复制初始化之间:
and similarly, between these two copy-initializations:
T x = a; // 1
T x = {a}; // 2
即带有 {..}
的使用列表初始化.{..}
称为 braced-init-list.
Namely, the ones with {..}
use list-initialization. The {..}
is called a braced-init-list.
因此,当您将 T x = a;
与 T x {a};
进行比较时,有 两个 的区别:copy- vs. 直接初始化,以及非列表"与列表初始化.正如其他人已经提到的和上面的引用,对于非类类型 T
,copy-init 和 direct-init 之间没有区别.但是,list-init 和没有 list-init 之间是有区别的.也就是说,我们也可以比较
So, when you compare T x = a;
to T x {a};
, there are two differences: copy- vs. direct-initialization, and "non-list-" vs. list-initialization. As already mentioned by others and in the quote above, for non-class types T
, there's no difference between copy- and direct-init. However, there's a difference between list-init and no list-init. That is, we could as well compare
int x (a);
int x {a};
在这种情况下,列表初始化禁止缩小转换.在 [dcl.init.list]/7 中将缩小转换定义为:
List-initialization in this case prohibits narrowing conversions. Narrowing conversions are defined in [dcl.init.list]/7 as:
窄化转换是隐式转换
从浮点类型到整数类型,或者
from a floating-point type to an integer type, or
从 long double
到 double
或 float
,或从 double
到 float
,除非源为常量表达式且转换后的实际值在可表示的取值范围内(即使不能准确表示),或者
from long double
to double
or float
, or from double
to float
, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented
(even if it cannot be represented exactly), or
从整数类型或无作用域枚举类型到浮点类型,除非源是一个常量表达式,转换后的实际值将适合目标类型并且将转换回原始类型时产生原始值,或
from an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type, or
从整数类型或无作用域枚举类型到不能代表所有的整数类型原始类型的值,除非源是一个常量表达式,其值在整数之后促销活动将适合目标类型.
from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
这篇关于C++11 中带或不带花括号的初始化差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!