https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98554
Bug ID: 98554 Summary: why the explicit conversion function of derived class return type is not a candidate in the context of direct-initialization Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: xmh970252187 at gmail dot com Target Milestone: --- #include <iostream> struct A{ A() = default; A(A const&){} }; struct B:A{}; struct C{ explicit operator B(){ return B{}; } }; int main(){ C c; A a(c); // #1 } In this example, GCC reports an error and the note is: return type 'B' of explicit conversion function cannot be converted to 'const A' with a qualification conversion The restriction for the second standard conversion of explicit conversion functions which shall be a qualified conversion is defined in the section [over.match.conv#1](https://eel.is/c++draft/over.match.conv#1). However, that section totally says about the initialization for an object of **non-class** type. In this example, the candidate functions should obey the rule defined in section [over.match.copy#1](https://eel.is/c++draft/over.match.copy#1), the relevant rule is: > When the type of the initializer expression is a class type “cv S”, > conversion functions are considered. The permissible types for non-explicit > conversion functions are T and any class derived from T. When initializing a > temporary object ([class.mem]) to be bound to the first parameter of a > constructor where the parameter is of type “reference to cv2 T” and the > constructor is called with a single argument in the context of > direct-initialization of an object of type “cv3 T”, the permissible types for > explicit conversion functions are the same; otherwise there are none. In this example, the object be direct-initialized is the `a` at #1, which has class type `A`, and the initializer is object `c` whose type is `C`. First, in order to initialize the object `a`, the following rule will be applied to >Otherwise, if the initialization is direct-initialization, or if it is >copy-initialization where the cv-unqualified version of the source type is the >same class as, or a derived class of, the class of the destination, >constructors are considered. The applicable constructors are enumerated >([over.match.ctor]), and the best one is chosen through overload resolution >([over.match]). Here, `A(A const&)` is a candidate function and its parameter is of type "reference to cv2 A", so the explicit conversion functions of class `C` should be considered. And the standard says "the permissible types for explicit conversion functions are the same". So in this context, `explicit operator B()` should be used in the conversion sequence. Moreover, since a conversion function whose return type is A can be used in this context, why wouldn't B which is derived A be. Isn't B is-A?