struct B {
B(int) {}
B(B const&) {}
};
struct D: B {
using B::B;
};
int main(void) {
B b(5);
D d(b); // error
return 0;
}
c++14 explicitly excludes copy/move constructors from inherited constructors in 12.9 [class.inhctor]/p3.
For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the complete class where the using-declaration appears or the constructor would be a default, copy, or move constructor for that class.
But I could not find any detailed descriptions in c++17. clang/gcc show that copy/move constructors of base class are not inherited. Can someone provide where it is explained in the standard? Thanks.
The new wording is in [over.match.funcs]/8:
A constructor inherited from class type
C
([class.inhctor.init]) that has a first parameter of type “reference to cv1P
” (including such a constructor instantiated from a template) is excluded from the set of candidate functions when constructing an object of type cv2D
if the argument list has exactly one argument andC
is reference-related toP
andP
is reference-related toD
. [ Example:struct A { A(); // #1 A(A &&); // #2 template<typename T> A(T &&); // #3 }; struct B : A { using A::A; B(const B &); // #4 B(B &&) = default; // #5, implicitly deleted struct X { X(X &&) = delete; } x; }; extern B b1; B b2 = static_cast<B&&>(b1); // calls #4: #1 is not viable, #2, #3, and #5 are not candidates struct C { operator B&&(); }; B b3 = C(); // calls #4
— end example ]
In your example, B
's inherited copy constructor is excluded from the set of candidates (that constructor has a first parameter of type reference to const B
, the argument list has exactly one argument - b
, and B
and D
are reference-related).