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.