zac*_*zac 19 c++ language-lawyer uniform-initialization c++11
我正在阅读C++ 11标准,但无法弄清楚是否
T x{};
Run Code Online (Sandbox Code Playgroud)
是值初始化或默认初始化(自动存储).它确实说得非常清楚:
10一个对象,其初始化程序是一组空的括号,即(),应进行值初始化.
然后
11如果没有为对象指定初始值设定项,则默认初始化该对象;
但我能找到的T x{};
是:
在表格T x(a)中发生的初始化; T x {a}; 以及在新表达式(5.3.4)中,static_cast表达式(5.2.9),函数表示法类型转换(5.2.3)以及基本和成员初始化器(12.6.2)称为直接初始化.
和
如果初始化程序是(非括号的)braced-init-list,则对象或引用是列表初始化的(8.5.4).
我很想进入阅读标准的水平.有人能指出我正确的方向吗?
M.M*_*M.M 26
您的报价确实涵盖了这一点:
如果初始化程序是(非括号的)braced-init-list,则对象或引用是列表初始化的(8.5.4).
跳过8.5.4列表初始化.在这里,我已经解释/省略了一些与以下情况无关的要点T x{}
:
列表初始化对象或类型T的引用定义如下:
- 如果T是聚合,则执行聚合初始化(8.5.1).
- 否则,如果初始化程序列表没有元素且T是具有默认构造函数的类类型,则对象将进行值初始化
- 否则,如果
T
是std::initializer_list<E>
[...] 的专业化- 否则,[如果列表不为空且与构造函数匹配]
- 否则,[如果列表只有一个元素]
- 否则,[if
T
是引用类型]- 否则,如果初始化列表没有元素,则对象进行值初始化.
- 否则,该计划是不正确的.
第一点,聚合初始化也在C++ 03中; 在这种情况下T x{};
是相同的T x = {};
.
对于第二点"T是具有默认构造函数的类类型",它是值初始化的,这意味着调用默认构造函数.
如果T
是基本类型,则应用倒数第二个点,并再次进行值初始化.
回到聚合初始化案例,在8.5.1/7中有:
如果列表中的initializer-clause少于聚合中的成员,那么未明确初始化的每个成员都应从其brace-or-equal-initializer初始化,或者如果没有bra-or-equal-initializer,从空的初始化列表(8.5.4).
所述支架或-等于初始值设定是指在类定义内联提供了一种初始化.如果不存在那么它被初始化,好像该成员已被初始化{}
(因此,这个逻辑被递归地应用于每个聚合成员).
例如,
struct T
{
int a;
};
Run Code Online (Sandbox Code Playgroud)
然后T x {};
导致a
被初始化,好像它是int a{};
,这是值初始化,因为int
是一个原始类型.
小智 8
虽然Matt McNabb已经介绍了这一点,但我会补充一点,如果您在浏览标准时遇到问题,那么查看cppreference并不会有什么坏处.他们关于列表初始化的部分很好地分解了它.
基本上,就像你的标准报价所说,T x{};
指的是:
使用括号括起的表达式列表或嵌套列表(braced-init-list)初始化命名变量.
和:
类型T对象的列表初始化的效果是:
- 如果braced-init-list为空且T是具有默认构造函数的类类型,则执行值初始化.
[...]
- 否则,如果braced-init-list没有元素,则T是值初始化的.
归档时间: |
|
查看次数: |
1015 次 |
最近记录: |