The move constructor in B
is deleted, but does not participate in overload resolution. According to cppreference:
The implicitly-declared or defaulted move constructor for class T is defined as deleted if any of the following is true:
- T has non-static data members that cannot be moved (have deleted, inaccessible, or ambiguous move constructors);
- T has direct or virtual base class that cannot be moved (has deleted, inaccessible, or ambiguous move constructors);
- T has direct or virtual base class or a non-static data member with a deleted or inaccessible destructor;
- T is a union-like class and has a variant member with non-trivial move constructor.
A defaulted move constructor that is deleted is ignored by overload resolution (otherwise it would prevent copy-initialization from rvalue).
The second bullet point applies: B
has a direct base class, A
, with a deleted move constructor. So B
's implicitly-declared move constructor is defined as deleted.
However, when the return statement is evaluating which constructor of B
to use, the deleted move constructor is not considered but the valid copy constructor is.
f
case should compile as well, according to this paragraph (C++17). The relevant part: "If the first overload resolution fails or was not performed, or if the type of the first parameter of the selected constructor is not an rvalue reference to the object's type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue." GCC works for me, but Clang does not: godbolt.org/z/8EbcnfTfb. – Fadge