首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我认为,在第8.5节[dcl.init]/17 in N4140中,子弹点(17.6.2)可能有一点不准确。

我认为,在第8.5节[dcl.init]/17 in N4140中,子弹点(17.6.2)可能有一点不准确。
EN

Stack Overflow用户
提问于 2015-10-20 17:23:13
回答 1查看 117关注 0票数 2

§8.5dcl.init/17 In N4140中的重点(17.6.2)中,我们有(重点是我的):

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

粗体文本的部分似乎表明直接初始化永远不会调用用户定义的转换序列。但这不是我在下面发现的

代码语言:javascript
复制
#include <iostream>

struct A {
    A() { std::cout << "default ctor A" << '\n'; }
    A(const A&) { std::cout << "copy A" << '\n'; }
};

struct C {
    C() { std::cout << "default ctor C" << '\n'; }
    operator A() { std::cout << "C::operator A()" << '\n'; return A(); };
};

int main()
{
     C c;
     A a{c};        // direct-initialization where the C::operator A() is invoked
                    // to copy construct the object `a`.
}

下面是由这个片段打印的:

代码语言:javascript
复制
default ctor C
C::operator A()
default ctor A
copy A
copy A

请参阅实例化

编辑

对于@Johannes的回答,请考虑A a(c);而不是A a{c};。据我所知,其余的仍然有效。

EN

回答 1

Stack Overflow用户

发布于 2015-10-20 18:34:19

我不明白你的担心,但回答发生了什么,以防这能帮你解决问题。A a{c}直接从dcl.initp17的项目1分支到dcl.init.list。

从这里开始,它将从一个const A&初始化一个C (通过over.match.list选择A的复制构造函数)。这将调用您引用的段落(首先分支到dcl.init.ref,然后依次应用dcl.initp17 )。这将构造一个正常的用户定义的转换序列,它能够使用转换函数,比如您的operator A

我认为您对以下事实感到困惑:它只提到了复制初始化的用户定义的转换序列,但在前面的符号中却没有提到。原因是在执行直接初始化时,这是对类的构造函数的概念上的直接调用,而不是转换(在转换中,对构造函数的调用只是一部分,在它之前(对于构造函数)和后面(对于转换函数/运算符)都是标准转换序列的一部分)。换句话说,对于直接初始化,您已经强制调用构造函数,而不是让编译器发现它需要这样做。而且您还没有“支付”用户定义的转换序列(不能嵌套用户定义的转换序列,因此它们是“宝贵的”)-编译器仍然可以应用用户定义的转换序列来匹配构造函数的参数。

但正确的测试用例是A a(c),而不是A a{c},以防止分支到dcl.init.list。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33242948

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档