Home > Blockchain >  Adding an explicit constructor makes a construction fail
Adding an explicit constructor makes a construction fail

Time:06-03

I would like to understand how the compiler is selecting constructor in the following situation

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
}

so that if we uncomment the explicit constructor, there will be no suitable constructor to call.

CodePudding user response:

X x({ 1, 2, 3 }); is direct initialization.

The behavior of your program can be explained using copy initialization's documentation notes which states:

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.

(emphasis mine)


And since in your given example there is no implicit conversion(as you've made that constructor explcit) from the initializer list, you get the mentioned error saying:

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

You can resolve this error by removing the explicit used for the concerned constructor X::X(int, int, int) as then there will be an implicit conversion available from the initializer list.


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

Because the explicit constructor X::X(int, int, int) that we provide also take part in overload resolution and it is a better match than the other constructor X::X(int, int, Y). And since it is a better match it is preferred but since it is explicit, we get the mentioned error.

  • Related