下面的初始化如何是格式良好的

How is the initialization below well-formed?

本文关键字:格式 初始化      更新时间:2023-10-16

[class.conv.]Ctor]/2包含以下初始化:

Z a3 = Z(1);    // OK: direct initialization syntax used

如何将其视为直接初始化语法?

Z(1)将直接初始化右值。然后使用右值初始化对象。根据保证省略的规则,不存在临时拷贝。右值直接初始化对象。因此,Z a3 = Z(1); Z a3(1);完全等价

在c++ 17之前的版本中,这将执行对一个右值临时对象的直接初始化,然后将这个临时对象复制到对象a3中(几乎可以肯定省略了)。无论副本是否省略,右值的初始化都是通过直接初始化进行的。a3的初始化是通过复制初始化,但这是通过复制构造函数进行的,而不是explicit

这是在谈论Z(1)。[dcl.init]/16:

初始化发生在[…]函数表示法转换(5.2.3)[…]]称为直接初始化

右值然后用于复制初始化z,这很好,保证省略与否- Z的复制/移动构造函数无论如何都不是explicit,因此即使没有c++ 17中的保证省略,初始化也很好。

(注意:我对新概念还不是很熟悉,但是下面的分析似乎是正确的)。首先,需要从函数强制转换表达式Z(1);开始。注意,这个prvalue表达式据说是使用直接初始化来初始化一些结果对象该对象是哪个,稍后将未指定并决定,不是由这个函数强制转换表达式决定!

现在,关于右值

的结果对象

右值的结果对象是由该右值初始化的对象;…[…对于丢弃的右值,将物化一个临时对象;参见条款[expr]. ...)

让我们首先为Z(1);做一个例子,这应该有助于理解这个概念。这是一个表达式语句,它是一个丢弃值表达式。对于这样的表达式,规则说

…如果表达式是一个右值…,则应用临时物化转换([convr .rval])。

每当应用这种"临时物化"转换时,就会创建一个临时对象,并从该prvalue初始化

这个转换通过用临时对象作为结果对象对右值求值来初始化一个T类型的临时对象([class.temporary]),并产生一个表示临时对象的xvalue

哇,所有这些都是像Z(1);这样的简单语句所需要的。现在谈谈你的案子,Z a3 = Z(1);。为此,8.6p17

更直接地指定结果对象

如果初始化表达式是一个右值,并且源类型的cv-不限定版本与目标类型的类是同一个类,则使用初始化表达式初始化目标对象。

Viola,这里有一个表达式,其语义是"将未知对象X直接初始化1",然后另一个规则提供了这个对象"X"。特别是,c++ 17之前的模型(每个类的值表达式直接创建对象)已经过时了。这特别意味着没有涉及复制构造函数或移动构造函数,但您的代码完全等同于 Z a3(1),据我所知。