【问题标题】:Copy constructor elision for direct initialization when the argument is converted to the destination type当参数转换为目标类型时,用于直接初始化的复制构造函数省略
【发布时间】:2019-01-21 20:46:32
【问题描述】:

这个问题是关于 c++ 标准的措辞的。

所有编译器,我认为这是应该的,省略用于初始化对象 b 波纹管 (assembly here) 的复制构造函数:

struct B;

struct A{
    operator B();
};

struct B{
    B(const B&);
    B(B&&);
};

void test(A a){
    B b(a);
}

但是当我阅读标准时,我不明白为什么会发生这种省略(我的粗体)[dcl.init]/17.6.2

否则,如果初始化是直接初始化,[...],则考虑构造函数。 枚举适用的构造函数([over.match.ctor]),并通过重载决议([over.match])选择最佳构造函数。 调用如此选择的构造函数来初始化对象,使用初始化表达式或表达式列表作为其参数。 如果没有构造函数适用,或者重载决议不明确,则初始化格式错误。

具体说是调用了构造函数。但是没有编译器会这样做。

我想我遗漏了一些东西或没有正确阅读标准。我应该如何阅读标准?


这与标准的前一段和下一段特别要求复制省略[dcl.init]/17.6.1形成对比:

如果初始化表达式是纯右值并且源类型的 cv 非限定版本与目标类是同一类,初始化表达式用于初始化目标对象

和 [dlc.init]/17.6.3:

否则(即,对于剩余的复制初始化情况),可以从源类型转换为目标类型的用户定义转换 [...] 以初始化表达式作为参数调用所选函数; [...] 该调用用于直接初始化,根据上述规则,作为复制初始化目标的对象。

最后一句将我送回 [dcl.init]/17.6.1,这也意味着复制省略。

【问题讨论】:

  • 似乎等同于copy_elision的示例
  • @Jarod42 我认为此页面上的所有示例都与 [dcl.init]/17.6.1 匹配,而不是困扰我的第 17.6.2 段。
  • 您希望编译器将a 对象转换为临时B 对象,然后在构造b 期间将该临时对象复制到b?它使用b 来存储a 转换为B 的返回值。
  • @1201ProgramAlarm 这是我在标准中读到的。根据我的阅读,复制省略不应该发生。

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


【解决方案1】:

@T.C.在评论中回答,这是核心语言问题CWG2327

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多