This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[Voted into the WP at the July, 2017 meeting.]
In an example like
struct A { A(int = 0); }; struct B : A { using A::A; }; B b0(0); // #1 B b; // #2
Is #2 valid (presumably calling the constructor inherited from A, or ill-formed due to ambiguity with 's implicit default constructor?
Proposed resolution (May, 2017):
Change 9.9 [namespace.udecl] paragraph 16 as follows:
For the purpose of forming a set of candidates during overload resolution, the functions that are introduced by a using-declaration into a derived class are treated as though they were members of the derived class. In particular, the implicit this parameter shall be treated as if it were a pointer to the derived class rather than to the base class. This has no effect on the type of the function, and in all other respects the function remains a member of the base class. Likewise, constructors that are introduced by a using-declaration are treated as though they were constructors of the derived class when looking up the constructors of the derived class (6.5.5.2 [class.qual]) or forming a set of overload candidates (12.2.2.4 [over.match.ctor], 12.2.2.5 [over.match.copy], 12.2.2.8 [over.match.list]). If such a constructor is selected to perform the initialization of an object of class type, all subobjects other than the base class from which the constructor originated are implicitly initialized (11.9.4 [class.inhctor.init]). [Note: A member of a derived class is sometimes preferred to a member of a base class if they would otherwise be ambiguous (12.2.4 [over.match.best]). —end note]
Insert the following as a new bullet following 12.2.4 [over.match.best] bullet 1.7:
...
F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 13.7.7.3 [temp.func.order], or, if not that,
F1 is a constructor for a class D, F2 is a constructor for a base class B of D, and for all arguments the corresponding parameters of F1 and F2 have the same type. [Example:
struct A {
A(int = 0);
};
struct B: A {
using A::A;
B();
};
int main() {
B b; // OK, B::B()
}
—end example], or, if not that,
F1 is generated from a deduction-guide (12.2.2.9 [over.match.class.deduct])...
This resolution also resolves issue 2277.