<html>
<head>
<title>n2203 Inheriting Constructors</title>
</head>

<body>
Document Number: n2203(2007-0063)<br/>
2007-03-09<br/>
Alisdair Meredith &lt;alisdair.meredith@uk.renaultf1.com><br/>
Michael Wong &lt;michaelw@ca.ibm.com><br/>
Jens Maurer &lt;Jens.Maurer@gmx.net><br/>

<h1>Inheriting Constructors</h1>

<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 forwarding constructors cannot be
declared by the user, such as for a dependant base class where a the class
template derives from one (or more) of its own template type parameters.
<p>
<h2>Outline of the Solution</h2>

After 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>forwarding
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 and <b>not</b> forwarded, deferring to the existing rules
for implicitly declaring copy/default constructors.
<p>
As forwarding constructors are implicitly declared, they do not inhibit the implicit
declaration of the default constructor.
<p>
Forwarding 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, forwarding 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 forwarding 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, and
it is even 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 of these would be ill-formed for
the same reason that multiple declarations of the same name are ill-formed.
<li></li>using base::base;
<li></li>using base::inherited;
<li></li>using inherited::base;
<li></li>using inherited::inherited;

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

<p>
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. That name is a synonym
for the name of some entity declared elsewhere.
<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 ]
<b>Moreover, 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.fwd).</b>
</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.  <b>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</b> <strike>Such a <em>using-declaration</em></strike>
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: <strike>since constructors and</strike> <b>Since</b> destructors do not
have names,</strike> a using-declaration cannot refer to <strike>a
constructor or </strike> 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 14 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).
<b>[Note: For <em>using-declaration</em>s that name a constructor, see
12.9 class.fwd]</b>
</blockquote>


Change 7.3.3 namespace.udecl paragraph 17 as follows
<blockquote>
All 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.  <b>[Note: Since constructors do not have names, these
access rules do not apply to constructors, see 12.9 class.fwd]</b>
...
</blockquote>

Change 7.3.3 namespace.udecl paragraph 18 as follows
<blockquote>
The alias <b>or the constructors</b> created by the <em>using-declaration</em>
has the usual accessibility for a <em>member-declaration</em>.
</blockquote>


Create a new section 12.9 class.fwd [not shown in bold here]:
<blockquote>
12.9 Forwarding Constructors   [class.fwd]
<p>
A <em>using-declaration</em> (7.3.3 namespace.udecl) that names a
constructor implicitly declares a set of <em>forwarding
constructors</em>.  For each non-template constructor other than a default or copy
constructor in the class named in the <em>using-declaration</em>, a
constructor is implicitly declared with the same parameter-type-list
(8.3.5 dcl.fct), <em>exception-specification</em> (15.4 except.spec),
and absence or presence of <code>explicit</code> (7.1.2 dcl.fct.spec),
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 member function template in the class
named in the <em>using-declaration</em>, a constructor member function
template is implicitly declared with the same template parameter list
(14.1 temp.param), parameter-type-list (8.3.5 dcl.fct),
<em>exception-specification</em> (15.4 except.spec), and absence or
presence of <code>explicit</code> (7.1.2 dcl.fct.spec), unless there
is an equivalent user-declared constructor member function template
(14.5.5.1 temp.over.link)  in the class where the
<em>using-declaration</em> appears.

[<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>Note:</em> If two <em>using-dclarations</em> declare forwarding
constructors with the same signatures, the program is ill-formed (9.2
class.mem).
<p>
<pre>
<code>
struct B1 {
  B1( int, int ) {}
};

struct B2 {
  B2( int, 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, int ) {} // User declaration resolved conflict
};
</code>
</pre>

 ]
<p>
An implicitly-declared forwarding 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
forwarding 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>using-declaration</em> and an
<em>expression-list</em> that forwards all constructor arguments in
order (12.6.2 class.base.init), and with an empty function body. If
that user-written constructor would be ill-formed, the program
is ill-formed.
<p>
Examples:
<pre>
<code>
struct B1 {
  B1( int, int ) {}
};

struct B2 {
  B2( double, double ) {}
};

struct D1 : B1 {
  using B1::B1;  // impliclty declare D1( int, int ) {}
  int x;
};

struct D2 : B2 {
  using B2::B2; // impliclty declare D2( double, double ) {}
  B1 b;
};
</code>
</pre>
D1 has an implicitly declared constructor D1(int, int) that will forward to
B1( int, int) if called, and will default initialize x.  As x is a POD in this case,
initialization will do nothing.  Class D1 also has an implicitly declared default
constructor, as the forwarding constructor is not user-declared.
<p>
B2 has an implicitly declared constructor D2( double, double ).  However, a
program that attempts to use this will be ill-formed, as data member b cannot
be default initialized.

<p>
<pre>
<code>
template< class T >
struct D : T {
  using T::T;
  ~D() { clog << "Destroying wrapper" << endl; }
};
</code>
</pre>
This example will wrap any class-type T and forward to all its constructors, while
writing a message to the standard log whenever such an object is destroyed.
</blockquote>


<p>
&nbsp;
<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.  Unrelated to the proposed semantics in
this paper, we propose to change 12.1 class.ctor paragraph 5 as follows
<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 <strike>default</strike> constructor
<b>with no arguments</b> is implicitly declared. ...
</blockquote>


</body>
</html>