当前位置: 首页 > 知识库问答 >
问题:

N3797的§8.5p17(初始化器的语义)中是否缺少一个大小写?

章盛
2023-03-14
struct S{int i, j;};

表单中发生的初始化

T x(a);
T x{a};

new表达式(5.3.4)、static_cast表达式(5.2.9)、函数符号类型转换(5.2.3)以及基和成员初始化器(12.6.2)中,也称为直接初始化。

但是§8.5p17似乎不是它们的特征:

如果目标类型是引用类型,请参见8.5.3。

如果目标类型是字符数组、char16_t数组、char32_t数组或wchar_t数组,并且初始值设定项是字符串文本,请参见8.5.2。

如果初始值设定项是(),则对象是值初始化的。

否则(即,对于剩余的复制初始化情况),如13.3.1.4所述,枚举可以从源类型转换到目标类型或(当使用转换函数时)转换到其派生类的用户定义的转换序列,并通过过载解析(13.3)选择最佳的转换序列。如果无法进行转换或转换不明确,则初始化格式不正确。所选函数以初始值设定项表达式作为参数调用;如果函数是构造函数,则调用初始化目标类型的CV非限定版本的临时值。临时的是PRValue。然后,调用的结果(对于构造函数来说是临时的)被用来根据上面的规则直接初始化作为复制初始化目标的对象。在某些情况下,允许一个实现通过将中间结果直接构造到正在初始化的对象中来消除这种直接初始化中固有的复制;见12.2、12.8。

否则,如果源类型是(可能是CV限定的)类类型,则考虑转换函数。列举了适用的转换函数(13.3.1.5),并通过过载解析选择了最佳转换函数(13.3)。这样选择的用户定义转换被调用,以将初始值设定项表达式转换为正在初始化的对象。如果无法进行转换或转换不明确,则初始化格式不正确。

否则,正在初始化的对象的初始值就是(可能是转换后的)初始化器表达式的值。如有必要,将使用标准转换(条款4)将初始值设定项表达式转换为目标类型的CV非限定版本;不考虑用户定义的转换。如果无法进行转换,则初始化格式不正确。[注意:“cv1T”类型的表达式可以独立于CV限定符cv1和CV2初始化“CV2T”类型的对象。

 int a;
 const int b = a;
 int c = b;
  • 不是列表初始化,因为每个初始化器都是一个带括号的braced-init-list
  • 目标类型不是引用
  • 目标类型通常不是字符数组。
  • 初始化器不是()
  • 目标类型不是数组。

共有1个答案

米修平
2023-03-14

这种情况包括在标准中:它是§8.5/17第6个子弹(强调是我的):

如果目标类型是(可能是CV限定的)类类型:

  • 如果初始化是直接初始化,或者如果初始化是复制初始化,源类型的CV限定版本与目标类型的类相同,或者是目标类型的派生类,则考虑构造函数。列举了适用的构造函数(13.3.1.3),并通过过载解析选择了最佳构造函数(13.3)。调用这样选择的构造函数来初始化对象,将初始化器表达式或表达式列表作为其参数。如果没有应用构造函数,或者重载解析不明确,则初始化格式不正确。
S(const S&) //copy
S(S&&)      //move

当引用类型的参数没有直接绑定到参数表达式时,转换序列是根据13.3.3.1将参数表达式转换为引用的基础类型所需的序列。概念上,此转换序列对应于用参数表达式复制初始化基础类型的临时值。顶级简历资格中的任何差异都包含在初始化本身中,并不构成转换。

由于s是一个聚合,我们必须应用§13.3.3.1.5/5来初始化这个临时对象:

否则,如果参数具有可以根据聚合初始化规则(8.5.1)从初始化器列表初始化的聚合类型,则隐式转换序列是用户定义的转换序列,而第二标准转换序列是标识转换。

 类似资料:
  • 按照对象的类型以及初始化时的上下文,C++提供了五花八门的对象初始化的方式。若不慎误用,可能会产生匪夷所思的谬误,而且还伴随着莫名其妙的错误(调试)信息。考虑如下的代码: string a[] = { “foo”, ” bar” }; //正确:初始化数组变量 //错误:初始化列表应用在了非聚合的向量上 vector<string> v = { “foo”, ” bar” }; void f(s

  • 问题内容: 显然,javac中初始化字符串的大小受到限制。谁能帮助我确定最大限额? 谢谢 编辑: 我们正在构建一个初始化字符串,看起来像这样的“ {1,2,3,4,5,6,7,8 ......}”,但理想情况下应包含10,000个数字。当我们为1000执行此操作时,10,000会引发错误,提示代码对于try语句而言太大。 为了产生这种效果,我们使用了一个stringbuilder并在附加值的数组上

  • 根据此堆栈溢出问题的公认(且唯一)答案, 使用 将改为零初始化对象。 那么,为什么呢?, 生成此输出: 定义的两个构造函数都是默认的?正当对于POD类型,默认初始化为零初始化。 根据这个问题的公认答案, 如果POD成员未在构造函数中初始化,也未在类初始化中通过C11初始化,则默认为已初始化。 不管是堆栈还是堆,答案都是一样的。 在C 98中(而不是之后),new int()被指定为执行零初始化。

  • 问题内容: 在Java中,但是在其他OO语言中,初始化属性定义之间也有区别,例如 并使用构造函数对其进行初始化? 我想不出任何实际的区别,有没有?否则,即使结果相同,是否存在一种方法优于另一种方法的情况? 问题答案: 初始化顺序在这里很重要。 将字段设置为默认初始值(0,false,null) 调用对象的构造函数(但不要执行构造函数的主体) 调用超类的构造函数 使用初始化程序和初始化块初始化字段

  • 问题内容: 我想知道如何初始化一个数组(或列表),但尚未填充值,以具有定义的大小。 例如在C中: 我该如何在python中做到这一点? 谢谢。 问题答案: 您可以使用:

  • 问题内容: 你可以通过执行以下操作来设置ArrayList的初始大小: 但是,你做不到 因为它会导致超出范围的异常。 如果无法访问分配的空间,设置初始大小有什么用? add函数的定义是,所以我不添加索引10。 问题答案: 你将数组列表的大小与其容量混淆了: 的大小是在列表中的元素的数目; 的容量是多少元素列表可以潜在地容纳而不重新分配其内部结构。 呼叫时,你是在设置列表的初始容量,而不是列表的大小