C++ tV{}初始化

C++ tV{}初始化,c++,c++11,language-lawyer,uniform-initialization,C++,C++11,Language Lawyer,Uniform Initialization,我正在阅读C++11标准,但不知道是否 T x{}; 值已初始化或默认已初始化(自动存储)。 它确实非常清楚地表明: 10初始值设定项为空括号集的对象,即(),应进行值初始化 那 11如果没有为对象指定初始值设定项,则该对象默认为已初始化 但是我能找到的关于tx{}是: 以T x(a)形式出现的初始化; tx{a}; 在新表达式(5.3.4)、静态转换表达式(5.2.9)、函数表示法类型转换(5.2.3)以及基和成员初始值设定项(12.6.2)中,都称为直接初始化 及 如果初始值设定项是一个(

我正在阅读C++11标准,但不知道是否

T x{};
值已初始化或默认已初始化(自动存储)。 它确实非常清楚地表明:

10初始值设定项为空括号集的对象,即(),应进行值初始化

11如果没有为对象指定初始值设定项,则该对象默认为已初始化

但是我能找到的关于
tx{}是:

以T x(a)形式出现的初始化; tx{a}; 在新表达式(5.3.4)、静态转换表达式(5.2.9)、函数表示法类型转换(5.2.3)以及基和成员初始值设定项(12.6.2)中,都称为直接初始化

如果初始值设定项是一个(非圆括号)带括号的初始列表,则对象或引用将被列表初始化(8.5.4)


我不太熟悉阅读标准的水平。有人能给我指出正确的方向吗?

这确实包含在你的报价中:

如果初始值设定项是一个(非圆括号)带括号的初始列表,则对象或引用将被列表初始化(8.5.4)

跳到8.5.4列表初始化。在这里,我解释/省略了一些与
tx{}
案例无关的要点:

类型为T的对象或引用的列表初始化定义如下:

  • 如果T是聚合,则执行聚合初始化(8.5.1)
  • 否则,如果初始值设定项列表没有元素,并且T是具有默认构造函数的类类型,则对象值已初始化
  • 否则,如果
    T
    std::initializer\u list
    […]的专门化
  • 否则,[如果列表不为空且与构造函数匹配]
  • 否则,[如果列表只有一个元素]
  • 否则,[如果
    T
    是参考类型]
  • 否则,如果初始值设定项列表没有元素,则对象值已初始化
  • 否则,程序的格式就不正确
第一点,聚合初始化也是在C++03中进行的;在这种情况下,
tx{}
tx={}相同

对于第二点“T是具有默认构造函数的类类型”,它是初始化的值,这意味着调用默认构造函数

如果
T
是基本类型,则应用倒数第二个点,并再次初始化该值

回到聚合初始化案例,在8.5.1/7中有:

如果列表中的初始值设定项子句少于聚合中的成员,则未明确初始化的每个成员应使用大括号或同等初始值设定项进行初始化,如果没有大括号或同等初始值设定项,则使用空初始值设定项列表(8.5.4)进行初始化

大括号或相等初始值设定项引用类定义中内联提供的初始值设定项。如果不存在此逻辑,则将其初始化,就像使用
{}
初始化成员一样(因此,此逻辑递归地应用于每个聚合成员)

比如说,

struct T
{
     int a;
};

然后
tx{}
导致
a
被初始化,就好像它是
inta{},这是值初始化,因为
int
是一种基本类型。

虽然Matt McNabb已经介绍了这一点,但我要补充的是,如果您在标准中导航时遇到问题,请检查。他们关于这方面的章节把它分解得很好

本质上,就像你的标准引用所说的,
tx{}指的是:

使用大括号括起来的变量列表初始化命名变量 表达式或嵌套列表(带大括号的初始化列表)

以及:

类型为T的对象的列表初始化的效果如下:

  • 如果带括号的init列表为空,并且T是具有默认构造函数的类类型,则执行值初始化
[……]

  • 否则,如果带大括号的init列表没有元素,则T值已初始化

谢谢你找到这个——我读列表初始化,并认为它隐含了使用1元素。看着这个,我同时感到既害怕又害怕C++。有很多东西要知道。非聚合的列表初始化是在C++11中添加的。。。它解决了一些问题(搜索“最烦人的解析”),但增加了一些新的奇怪的情况