Issue2273

Title 2273. Inheriting constructors vs implicit default constructor
Status drwp Section 15.1 [class.ctor]
Submitter Richard Smith

Created on 2016-06-17.00:00:00 by admin, last changed by admin.

Messages
msg6103 (view) Date: 2017-07-15.00:00:00

[Voted into the WP at the July, 2017 meeting.]

msg6102 (view) Date: 2017-05-15.00:00:00

Proposed resolution (May, 2017):

  1. Change 10.3.3 [namespace.udecl] paragraph 16 as follows:

  2. 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.4.3.1 [class.qual]) or forming a set of overload candidates (16.3.1.3 [over.match.ctor], 16.3.1.4 [over.match.copy], 16.3.1.7 [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 (15.6.3 [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 (16.3.3 [over.match.best]). —end note]
  3. Insert the following as a new bullet following 16.3.3 [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 17.6.6.2 [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 (16.3.1.8 [over.match.class.deduct])...

This resolution also resolves issue 2277.

msg5912 (view) Date: 2018-02-27.00:00:00

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?

History
Date User Action Args
2018-02-27 00:00:00adminsetstatus: open -> drwp
section: 12.1 [class.ctor] -> 15.1 [class.ctor]
2018-02-27 00:00:00adminsetmessages: + msg6103
2018-02-27 00:00:00adminsetmessages: + msg6102
2016-06-17 00:00:00admincreate