Per § 12.2.2.1 [over.match.funcs.general]/9-sentence-2:
A constructor inherited from class type C ([class.inhctor.init]) that has a first parameter of type “reference to cv1 P” (including such a constructor instantiated from a template) is excluded from the set of candidate functions when constructing an object of type cv2 D if the argument list has exactly one argument and C is reference-related to P and P is reference-related to D.
I am just trying to understand this paragraph and somehow conduct an example that matches the wording then I want to apply that example to the paragraph:
struct P;
struct C { C(); C(const P&); };
struct P : C { using C::C; };
struct D : P {};
D d{ P() };
From the above example: C is reference-related to P and P is reference-related to D. And there's a constructor inherited from class type C that has a first parameter of type “reference to cv1 P”. And when constructing an object of type cv D -and the argument list has exactly one argument which is P()- then this inherited constructor is excluded from the set of candidate functions.
Does my example match what the wording intends? And Do I understand and parse the wording correctly? Also, Is there any other wording regarding this point (inheriting copy/move constructors)?
This example has nothing to do with inheriting constructors: it works even with either or both of
C(const P&);andusing C::C;removed. It’s doing aggregate initialization of aDby supplying a value for its one subobject (the baseP).Note that there is no “compiler-generated
D::D(const P&)”, although the effect is similar to what one might expect it to do. In C++17, changing toD d((P()));fails, but C++20 lets that be aggregate initialization too.