下面的初始化如何是格式良好的
How is the initialization below well-formed?
[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);
做一个例子,这应该有助于理解这个概念。这是一个表达式语句,它是一个丢弃值表达式。对于这样的表达式,规则说
每当应用这种"临时物化"转换时,就会创建一个临时对象,并从该prvalue初始化。…如果表达式是一个右值…,则应用临时物化转换([convr .rval])。
这个转换通过用临时对象作为结果对象对右值求值来初始化一个T类型的临时对象([class.temporary]),并产生一个表示临时对象的xvalue
哇,所有这些都是像Z(1);
这样的简单语句所需要的。现在谈谈你的案子,Z a3 = Z(1);
。为此,8.6p17
如果初始化表达式是一个右值,并且源类型的cv-不限定版本与目标类型的类是同一个类,则使用初始化表达式初始化目标对象。
Viola,这里有一个表达式,其语义是"将未知对象X直接初始化1",然后另一个规则提供了这个对象"X"。特别是,c++ 17之前的模型(每个类的值表达式直接创建对象)已经过时了。这特别意味着没有涉及复制构造函数或移动构造函数,但您的代码完全等同于 Z a3(1)
,据我所知。
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 如何使用 clang 格式格式化地图初始化?
- C :适当的格式以初始化派生和基础
- 静态constexpr变量的自初始化,格式是否正确
- 下面的初始化如何是格式良好的
- 代码是否被视为可移植可执行文件格式中的初始化数据,初始化数据和单元化数据之间的确切区别是什么
- C3015:OpenMP 'for'语句中的初始化格式不正确