为什么调用`A a(c);`在main()中不明确?

时间:2016-08-27 21:44:01

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

为什么A a(c);中的main()来电不明确?

struct C;

struct A {

    A() { std::cout << "default ctor A" << '\n'; }
    A(const A&) { std::cout << "copy A" << '\n'; }
    A(C&) { std::cout << "ctor A(C)" << '\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); 
}

代码打印(clang和GCC):

default ctor C
ctor A(C)

如果我们注释掉构造函数A :: A(C&amp;),则代码打印出来:

default ctor C
C::operator A()
default ctor A
copy A
copy A

1 个答案:

答案 0 :(得分:3)

如果你有这个,那么重载解析过程的目标是确定如何将C转换为A ,那么它确实是模棱两可的,因为可以使用转换构造函数或转换函数:

void f(A);
f(c);

但是,这与以下情况不同:

A a(c);

这里,重载决策用于确定要调用的A的构造函数,因此它选择其参数类型与参数类型完全匹配的构造函数。

标准参考是C ++ 14中的[over.match.ctor] / 1:

  

当类类型的对象被直接初始化(8.5),或者从类型或表达式中复制初始化时   派生类类型(8.5),重载决策选择构造函数。对于直接初始化,候选人   函数是正在初始化的对象的类的所有构造函数。对于复制初始化,   候选函数是该类的所有转换构造函数(12.3.1)。参数列表是   初始值设定项的表达式列表赋值表达式