添加显式构造函数会使构造失败

Adding an explicit constructor makes a construction fail

我想了解编译器在以下情况下如何选择构造函数

class Y
{
public:
    Y(int) {}
};

class X
{
public:
    X(int, int, Y) { cout << "Y\n"; }
    //explicit X(int, int, int) { cout << "3 ints\n"; }
};


int main()
{
    X x({ 1, 2, 3 });  // Y
}

这样如果我们取消注释 explicit 构造函数,将没有合适的构造函数可以调用。

X x({ 1, 2, 3 });直接初始化.

您的程序的行为可以使用 copy initialization's documentation notes 来解释,其中指出:

In addition, the implicit conversion in copy-initialization must produce T directly from the initializer, while, e.g. direct-initialization expects an implicit conversion from the initializer to an argument of T's constructor.

(强调我的)


并且由于在您给定的示例中没有从初始化列表中进行隐式转换(因为您已经创建了构造函数 explcit),所以您会收到提到的错误:

error: converting to ‘X’ from initializer list would use explicit constructor ‘X::X(int, int, int)’

您可以通过删除用于相关构造函数 X::X(int, int, int)explicit 来解决此错误,因为这样就可以从初始化列表中获得隐式转换。


but why can't X x({ 1, 2, 3 }); keep using X::X(int, int, Y) when X::X(int, int, int) is explicit?

因为我们提供的显式构造函数X::X(int, int, int)也参与了重载决议,它比其他构造函数X::X(int, int, Y)更匹配。由于它是一个更好的匹配,因此它是首选,但由于它是 explicit,我们得到了提到的错误。