<html>
  <head>
    <title>N2540 Inheriting Constructors (revision 5)</title>
    <base href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/" />
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <style type="text/css">
      /* <![CDATA[*/
        address {text-align: right}
        p {text-align:justify}
        li {text-align:justify}
        ins {background-color:#FFFF99}
        del {background-color:#FF9999}
     /* ]]> */
    </style>
  </head>

<body>
Document Number: N2540=08-0050<br/>
2008-02-29<br/>
Alisdair Meredith &lt;alisdair.meredith@codegear.com><br/>
Michael Wong &lt;michaelw@ca.ibm.com><br/>
Jens Maurer &lt;Jens.Maurer@gmx.net><br/>

<h1>Inheriting Constructors (revision 5)</h1>

This paper is a revision of <a href="n2512.html">N2512</a> "Inheriting Constructors (revision 4)" by Alisdair Meredith, Michael Wong, Jens Maurer.


<h2>Problem Description</h2>

There is often a desire to initialize a derived class with exactly the same set of constructors as its base.  This typically ends up with a series of tediously simply forwarding declarations and definitions.  This work could be more easily handled by the compiler, is less error-prone when handled by the compiler, and the intent is clearer to read if the forwarding problem can be reduced to a single statement.
<p>
There are also a couple of cases where the inheriting constructors cannot be declared by the user, such as for a dependant base class where a class template derives from one (or more) of its own template type parameters.
<p>
<h2>Outline of the Solution</h2>

Initial analysis was supplied by Francis Glassborow (N1583) and after further feedback from the evolution group, the direction was to word the simplest feature possible without making any effort to support extended use cases. The more complicated examples will probably be handled by a different language feature - a variadic constructor template.
<p>
The basic idea is to extend using declarations to support constructors.  This falls out of the grammar today (no grammar changes required) and simply extends the semantic rules to cover the new case.
<p>
When a using declaration names a base class constructor, a number of <em>inheriting constructors</em> are implicitly declared in the derived class.  Like other implicitly declared constructors, they are only implicitly defined if they are <em>used</em>.
<p>
Copy and default constructors are <b>not</b> forwarded, deferring to the existing rules for implicitly declaring copy/default constructors.
<p>
As inheriting constructors are implicitly declared, they do not inhibit the implicit declaration of the default constructor.
<p>
inheriting constructors retain the throw spec and explicitness of the base constructor.
<p>
User declared constructors inhibit forwarding for that particular signature, much as user declaration of a function would hide a specific signature when using declarations are used with regular functions.
<p>
It is an error for multiple using declarations to refer to the same base class.  If multiple using directives declare the same signature, the program is ill-formed, even if those constructors are not used.  This can be worked around with a user-declared constructor instead.
<p>
A program is ill-formed if a fowarding constructor is used that forwards to a base class constructor that is declared private.  Note that this is different to the using declarations with regular functions, that are ill-formed even if the private function is not used.  It is consistent with the way a variadic constructor template would work though.
<p>
Typically, inheriting constructor definitions for classes with virtual bases will be ill-formed, unless the virtual base supports default initialization, or the virtual base is a direct base, and named as the base forwarded-to.  Likewise, all data members and other direct bases must support default initialization, or any attempt to use a inheriting constructor will be ill-formed.  Note: ill-formed when used, not declared.
<p>
Note that typedef names that alias a direct base will work in the same way, but it is not possible to mix and match names either side of the ::.<br>
For example:
<blockquote>
<pre>
<code>
struct derived : base {
  typedef base inherited;
};
</code>
</pre>
</blockquote>

The following would all be valid using declarations, and all mean the same thing. Attempting to use any combination of more than one of these would be ill-formed for the same reason that multiple declarations of the same name are ill-formed.
<ul>
<li>using base::base;</li>
<li>using inherited::inherited;</li>
</ul>

The following are ill-formed in this example, but theoretically might match an otherwise hidden function declaration as a regular using-declaration.  Do we need to explicitly ban these forms?
<ul>
<li>using base::inherited;</li>
<li>using inherited::base;</li>
</ul>


<h2>Unrelated Issue</h2>

<p>
While drafting the wording for this paper, it occurred to one of the
authors that the standard currently defines "default constructor" in
terms of whether a constructor can be called with no arguments. Thus,
for a class C, C(int x = 42) is a default constructor.  An implicitly
declared default constructor could have that signature, which seems a
bit surprising.  The wording below contains a change to 12.1
class.ctor to prohibit such strange implicitly-declared default
constructors.
</p>


    <h2>Summary of Changes</h2>

    Changes since n2512:
    <ul>
      <li>Implement Bellevue review comments from CWG</li>
      <li>Support for default parameters</li>
      <li>Define term <em>constructor characteristics</em>
    </ul>

    Changes since n2438:
    <ul>
      <li>discard new keyword <code>base_constructors</code></li>
      <li>revert to "using T::T" syntax</li>
      <li>"using T::T" requires the same identifer on both sides of ::</li>
    </ul>

    Changes since n2376:
    <ul>
      <li>add new keyword <code>base_constructors</code></li>
      <li>apply "using base_constructors T" syntax</li>
      <li>
        adopt the term <em>inheriting constructor</em> in preference to
        <em>forwarding constructor</em>
      </li>
      <li>clean up examples in non-normative notes</li>
    </ul>

    Changes since n2254:
    <ul>
      <li>
        apply "using default T" syntax, which is not riding on the grammar
        for <em>using-declaration</em> any more.
      </li>
      <li>handle deleted constructors</li>
    </ul>

    Changes accumulated since CWG review in Oxford:
    <ul>
      <li>handle constexpr</li>
      <li>properly forward rvalues</li>
      <li>handle name lookup</li>
    </ul>

<h2>Proposed Changes to the Working Paper</h2>

Change 3.4.3.1 class.qual paragraph 2 as indicated:
<blockquote>

In a lookup in which the constructor is an acceptable lookup
result<del>,</del> <ins>and</ins>
if the <em>nested-name-specifier</em> nominates a class C<ins>:</ins>
<ul>
<li><ins>if the name specified after the
<em>nested-name-specifier</em>, when looked up in C, is the
injected-class-name of C (clause 9), or</ins></li>
<li><ins>if the name specified after the
<em>nested-name-specifier</em> is the same as the <em>identifier</em>
or the <em>simple-template-id</em>'s <em>template-name</em> in
the last component of the <em>nested-name-specifier</em>,</ins> </li>
</ul>

<del>, and the name specified after the
<em>nested-name-specifier</em>, when looked up in C, is the
injected-class-name of C (clause 9)</del> the name is instead
considered to name the constructor of class C.

[ Note: For example, the constructor is not an acceptable lookup
result in an <em>elaborated-type-specifier</em> so the constructor
would not be used in place of the injected-class-name. ]

Such a constructor name shall be used only in the declarator-id of a
declaration that names a constructor <ins>or in a
<em>using-declaration</em>.</ins>
</blockquote>

Change 7.3.3 namespace.udecl paragraph 1 as follows

<blockquote>
A <em>using-declaration</em> introduces a name into the declarative
region in which the <em>using-declaration</em> appears. <del>That name is a
synonym for the name of some entity declared elsewhere.</del>
<p>
<pre>
<em>using-declaration:</em>
  using typename<sub><em>opt</em></sub> ::<sub><em>opt</em></sub> <em>nested-name-specifier unqualified-id</em> ;
  using :: <em>unqualified-id</em> ;
</pre>

<p>
The member name specified in a <em>using-declaration</em> is declared
in the declarative region in which the <em>using-declaration</em>
appears. [Note: only the specified name is so declared; specifying an
enumeration name in a <em>using-declaration</em> does not declare its
enumerators in the <em>using-declaration</em>'s declarative region. --
end note ]

<ins>If a <em>using-declaration</em> names a constructor
(3.4.3.1 class.qual), it implicitly declares a set of constructors in
the class in which the <em>using-declaration</em> appears (12.9
class.inh-ctor); otherwise the name specified in a
<em>using-declaration</em> is a synonym for the name of some entity
declared elsewhere.
</ins>

</blockquote>

Change 7.3.3 namespace.udecl paragraph 3 as follows
<blockquote>

In a <em>using-declaration</em> used as a <em>member-declaration</em>,
the <em>nested-name-specifier</em> shall name a base class of the
class being defined.  <ins>If such a <em>using-declaration</em> names
a constructor, the <em>nested-name-specifier</em> shall name a direct
base class of the class being defined; otherwise it</ins> <del>Such a
<em>using-declaration</em></del> introduces the set of declarations
found by member name lookup (10.2, 3.4.3.1).

</blockquote>

Change 7.3.3 namespace.udecl paragraph 4 as follows

<blockquote>

[ Note: <del>since constructors and</del> <ins>Since</ins> destructors
do not have names<del>,</del> a using-declaration cannot refer to
<del>a constructor or </del> a destructor for a base class. Since
specializations of member templates for conversion functions are not
found by name lookup, they are not considered when a using-declaration
specifies a conversion function (14.5.2). -- end note ] ...

</blockquote>

Change 7.3.3 namespace.udecl paragraph 15 as follows
<blockquote>

When a <em>using-declaration</em> brings names from a base class into
a derived class scope, member functions and member function templates
in the derived class override and/or hide member functions and member
function templates with the same name, parameter-type-list (8.3.5),
and cv-qualification in a base class (rather than conflicting).
<ins>[Note: For <em>using-declaration</em>s that name a constructor,
see 12.9 class.inh-ctor.]</ins>

</blockquote>


Change 7.3.3 namespace.udecl paragraph 18 as follows
<blockquote>

<ins>The access rules for inheriting constructors are specified in 12.9
class.inh-ctor; otherwise all</ins> <del>All</del> instances of the name
mentioned in a <em>using-declaration</em>
shall be accessible. In particular, if a derived class uses a
<em>using-declaration</em> to access a member of a base class, the
member name shall be accessible. If the name is that of an overloaded
member function, then all functions named shall be accessible.  The
base class members mentioned by a <em>using-declaration</em> shall be
visible in the scope of at least one of the direct base classes of the
class where the <em>using-declaration</em> is specified.  ...

</blockquote>

Change 7.3.3 namespace.udecl paragraph 19 as follows
<blockquote>

The alias created by the <em>using-declaration</em> has the usual
accessibility for a <em>member-declaration</em>.  <ins>[Note: A
<em>using-declaration</em> that names a constructor does not create
aliases; see 12.9 class.inh-ctor for the pertinent accessibility rules.]</ins>

</blockquote>


Create a new section 12.9 class.inh-ctor [not shown in bold here]:
<blockquote> 12.9 Inheriting Constructors [class.inh-ctor]
<p>

A <em>using-declaration</em> (7.3.3 namespace.udecl) that names a
constructor implicitly declares a set of <em>inheriting
constructors</em> as follows:

The <em>candidate set of inherited constructors</em> from the class X
named in the <em>using-declaration</em> consists of actual constructors and
notional constructors that result from the transformation of defaulted
parameters as follows:
<ul>
<li>all non-template constructors of X, and</li>
<li>for each non-template constructor of X that has at least one
parameter with a default argument, the set of constructors that
results from omitting any ellipsis parameter specification and
successively omitting parameters with a default argument from
the end of the parameter-type-list, and</li>
<li>all constructor templates of X, and</li>
<li>for each constructor template of X that has at least one parameter
with a default argument, the set of constructor templates that results
from omitting any ellipsis parameter specification and
successively omitting parameters with a default argument from the end of the parameter-type-list.</li>
</ul>

The <em>constructor characteristics</em> of a constructor
or constructor template are
<ul>
<li>the template parameter list (14.1 temp.param), if any,</li>
<li>the parameter-type-list (8.3.5 dcl.fct),</li>
<li>the <em>exception-specification</em> (15.4 except.spec),</li>
<li>absence or presence of <code>explicit</code> (12.3.1 class.conv.ctor), and</li>
<li>absence or presence of <code>constexpr</code> (7.1.5 dcl.constexpr).</li>
</ul>

For each non-template constructor in the candidate set of inherited
constructors other than a constructor having no parameters or a copy
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 class where
the <em>using-declaration</em> appears.  Similarly, for each
constructor template in the candidate set of inherited constructors,
a constructor template is implicitly
declared with the same constructor characteristics unless there is an
equivalent user-declared constructor template (14.5.6.1
temp.over.link) in the class where the <em>using-declaration</em>
appears. [ Note: Default arguments are not inherited. ]
</p>

<p>
A constructor so declared has the same access as the corresponding
constructor in X.  It is deleted if the corresponding constructor
in X is deleted (8.4 dcl.fct.def).
</p>

[<em>Note:</em> Default and copy constructors may be implicitly
declared as specified in 12.1 class.ctor and 12.8 class.copy.]
<p>
[<em>Example: </em>
</p>
<pre>
<code>
struct B1 {
  B1( int );
};

struct B2 {
  B2( int = 13, int = 42 );
};

struct D1 : B1 {
  using B1::B1;
};


struct D2 : B2 {
  using B2::B2;
};
</code>
</pre>
<p>
The candidate set of inherited constructors in D1 for B1 is
<ul>
<li>B1( const B1 & )</li>
<li>B1( int )</li>
</ul>
</p>
<p>
The set of constructors present in D1 is
<ul>
<li>D1() implicitly declared default constructor, ill-formed if used</li>
<li>D1( const D1 & ) implicitly declared copy constructor, not inherited</li>
<li>D1( int ) implicitly declared inheriting constructor</li>
</ul>
</p>
<p>
The candidate set of inherited constructors in D2 for B2 is
<ul>
<li>B2( const B2 & )</li>
<li>B2( int = 13, int = 42 )</li>
<li>B2( int = 13 )</li>
<li>B2()</li>
</ul>
</p>
<p>
The set of constructors present in D2 is
<ul>
<li>D2() implicitly declared default constructor, not inherited</li>
<li>D2( const D2 & ) implicitly declared copy constructor, not inherited</li>
<li>D2( int, int ) implicitly declared inheriting constructor</li>
<li>D2( int ) implicitly declared inheriting constructor</li>
</ul>
</p>
<p>
]
</p>


[<em>Note:</em> If two <em>using-declarations</em> declare inheriting
constructors with the same signatures, the program is ill-formed (9.2
class.mem, 13.1 over.load), because an implicitly-declared constructor
introduced by the first <em>using-declaration</em> is not a user-declared
constructor and thus does not preclude another declaration of a
constructor with the same signature by a subsequent
<em>using-declaration</em>.
[<em>Example: </em>
</p>
<p>
<pre>
<code>
struct B1 {
  B1( int );
};

struct B2 {
  B2( int );
};

struct D1 : B1, B2 {
  using B1::B1;
  using B2::B2;  // ill-formed: implicitly declaring same ctor twice
};

struct D2 : B1, B2 {
  using B1::B1;
  using B2::B2;
  D2( int );  // ok: user declaration prevents conflict
};
</code>
</pre>
 ] ]
<p>
An inheriting constructor for a class is
implicitly defined when it is used (3.2 basic.def.odr) to create an
object of its class type (1.8 intro.object).  An implicitly-defined
inheriting constructor performs the set of initializations of the
class that would be performed by a user-written <code>inline</code>
constructor for that class with a <em>mem-initializer-list</em> whose
only <em>mem-initializer</em> has a <em>mem-initializer-id</em> that
names the base class named in the
<em>nested-name-specifier</em> of the <em>using-declaration</em> and an
<em>expression-list</em> as specified below, and where the
<em>compound-statement</em> in its function body is empty (12.6.2
class.base.init).  If that user-written
constructor would be ill-formed, the program is ill-formed.  Each
<em>expression</em> in the <em>expression-list</em> is of the form
<code>static_cast&lt;<em>T</em>&amp;&amp;>(<em>p</em>)</code> where
<code><em>p</em></code> is the name of the corresponding constructor
parameter and <code><em>T</em></code> is the declared type of
<code><em>p</em></code>.
</p>

<p>
[ Example:
<pre>
<code>
struct B1 {
  B1( int ) {}
};

struct B2 {
  B2( double ) {}
};

struct D1 : B1 {
  using B1::B1; // implicitly declares D1( int )
  int x;
};

void test() {
  D1 d(6);        // ok; d.x is not initialized
  D1 e;           // error: D1 has no default constructor
}

struct D2 : B2 {
  using B2::B2; // ok, implicitly declares D2( double )
  B1 b;
};

D2 f(1.0);      // error: B1 has no default constructor

template&lt; class T &gt;
struct D : T {
  using T::T;   // declares all constructors from class T
  ~D() { std::clog &lt;&lt; "Destroying wrapper" &lt;&lt; std::endl; }
};
</code>
</pre>
</p>
<p>
Class template <code>D</code> wraps any class and forwards all its
constructors, while writing a message to the standard log whenever an
object of class <code>D</code> is destroyed.
]
</p>

</blockquote>

<p>Change 12.1 class.ctor paragraph 5 as follows</p>

<blockquote>
A <em>default constructor</em> for a class X is a constructor of class
X that can be called without an argument. If there is no user-declared
constructor for class X, a <del>default</del> constructor <ins>having no
parameters</ins> is implicitly declared. ...
</blockquote>

</body>
</html>
