如何初始化良好的初始化?

时间:2016-08-23 19:58:58

标签: c++ initialization language-lawyer c++17

[class.conv.ctor]/2中的示例包含以下初始化:

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

这如何被视为直接初始化语法?

3 个答案:

答案 0 :(得分:8)

Z(1)会直接初始化一个prvalue。然后,prvalue将用于初始化对象。到rules of guaranteed elision,没有临时跟随副本。 prvalue直接初始化对象。因此,Z a3 = Z(1); 完全等同于Z a3(1);

在前C ++ 17中,这将执行prvalue临时的直接初始化,然后是临时的(几乎肯定省略的)副本到对象a3。无论副本是否被省略,prvalue的初始化都是通过直接初始化来完成的。 a3的初始化是通过复制初始化,但这是通过复制构造函数,而不是explicit

答案 1 :(得分:4)

它在讨论Z(1)。 [dcl.init] / 16:

  

以[...]功能表示法类型发生的初始化   转换(5.2.3)[...]称为直接初始化

然后prvalue用于复制初始化z,这很好,保证省略或不用 - Z的复制/移动构造函数不是{{1}无论如何,即使没有C ++ 17中保证的省略,初始化也很好。

答案 2 :(得分:2)

(谨慎提醒:我对新概念还不是很熟悉,但以下分析似乎是正确的)。首先,您需要从功能表达式Z(1);开始。请注意,此 prvalue 表达式用于使用 direct-initialization 初始化某些结果对象这个这个对象是未指定的,稍后决定,这个函数化的表达式!

现在,关于prvalues的结果对象

  

prvalue的结果对象是由prvalue初始化的对象; ...... [...对于丢弃的prvalue,临时对象实现;见条款[expr]。 ......]

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

  

...如果表达式是prvalue ...,则应用临时实现转换([conv.rval])。

每当这个"临时实现"应用转换,创建临时对象并从该prvalue 初始化

  

此转换通过使用临时对象作为结果对象计算prvalue,从prvalue初始化T类型的临时对象([class.temporary]),并生成表示临时对象的xvalue

哇,像Z(1);之类的简单陈述需要这一切。现在关于你的案例,Z a3 = Z(1);。为此,结果对象更直接由8.6p17

指定
  

如果初始化表达式是prvalue且源类型的cv-nonqualified版本与目标类相同,则初始化表达式用于初始化目标对象。

Viola,我们有一个表达式,其语义是&#34;用1&#34;直接初始化一个未知的对象X,然后另一个规则提供这个对象&#34; X&#34;。特别是,每个class-prvalue epxression直接创建对象的pre-C ++ 17模型已经过时。这尤其意味着没有涉及复制构造函数或移动构造函数,但据我所知,您的代码与<{em>完全等效Z a3(1)