问题描述
我们可以在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
长版
形式的初始化
Long version
An initialization of the form
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:
因此对于非类类型,初始化的 form 无关紧要。但是,这两个直接初始化之间是有区别的:
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
即,带有 {..}
使用列表初始化。 {..}
被称为括号初始化列表。
Namely, the ones with {..}
use list-initialization. The {..}
is called a braced-init-list.
所以,当您将 T x = a;
与 T x {a};
进行比较时,有两个差异:复制与直接初始化,以及非列表与列表初始化。正如其他人已经提到的,以及在上面的引用中,对于非类类型 T
,copy-init和direct-init之间没有区别。但是,list-init和no 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中带有或不带有花括号的初始化差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!