我们在C++中可以用两种方式来初始化变量。
第一种:
int abc = 7;
二:
int abc {7};
这两种方法有什么区别?编译器是否会以不同的方式处理它们,或者在执行代码的方式上有所不同?
int abc = 7;
二:
int abc {7};
这两种方法有什么区别?编译器是否会以不同的方式处理它们,或者在执行代码的方式上有所不同?
通过{..}
进行初始化是列表初始化,它禁止缩小转换。例如,如果LLONG_MAX
是long long int
的最大值,而你的int
不能表示它:
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。
[dcl.init]/14 表示:
初始化的形式(使用括号或者等号)通常是无关紧要的,但当初始化器或被初始化实体具有类类型时则有所不同;请参见下面。
因此,在非类类型中,初始化的形式并不重要。但是,这两种直接初始化之间存在差异:
T x(a); // 1
T x{a}; // 2
同样地,在这两个复制初始化之间:
T x = a; // 1
T x = {a}; // 2
{..}
的使用列表初始化。 {..}
被称为花括号初始化列表。T x = a;
和T x {a};
时,存在两个区别:复制与直接初始化以及“非列表”与列表初始化。如其他人和上面的引用已经提到的那样,对于非类类型T
,复制和直接初始化之间没有区别。但是,在列表初始化和没有列表初始化之间存在区别。也就是说,我们同样可以比较int x (a);
int x {a};
std::random_device{}()
? - moooeeeepstd::random_device{}
构造了一个std::random_device
类型的临时对象,然后调用该对象重载的operator()
,就像std::random_device rd; rd()
一样。random_device
有一个operator()
,它会调用RNG并返回一个(伪)随机数,请参见http://en.cppreference.com/w/cpp/numeric/random/random_device/operator()。 - dyp尽管对于int
类型的现有回复已经很完整了,但我痛苦地发现,在某些情况下,()
和{}
初始化之间存在其他差异。
关键词是{}
是一个初始化列表。
其中一种情况是使用char
的count
副本来初始化std::string
:
std::string stars(5, '*')
将会把stars
初始化为*****
,但是
std::string stars{5, '*'}
将被解读为std::string stars(char(5), '*')
并将星号初始化为*
(前面有一个隐藏字符)。
int
类型来说,唯一的区别是{}
语法禁止缩窄转换,例如从字面量转换为过大而无法容纳在int
中。对于类类型,根据您想了解差异的详细程度不同,情况可能会变得更加复杂。 - dyp