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 aD
by 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.