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

<body>
Document Number: n2119(2006-0189)<br/>
2006-10-19<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>

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>
[grammar snippet is ok]
<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 member-declaration, 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, it shall name a constructor of a direct base class,
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: since <strike>constructors and</strike> 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 using-declaration 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
using-declaration 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>If the <em>using-declaration</em> names a constructor,
all base class constructors forwarded to (12.9 class.fwd) shall be
accessible.</b>
...
</blockquote>

Change 7.3.3 namespace.udecl paragraph 18 as follows
<blockquote>
The alias <b>or the constructors</b> created by the using-declaration
has the usual accessibility for a member-declaration.
</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>. Candidates are all constructors of the class named in the
<em>using-declaration</em>, except default and copy constructors and
those with an ellipsis parameter. For each non-template candidate, 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
among the candidates, 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
constructors (12.8) may be implicitly declared as specified in
12.1 class.ctor and 12.8 class.copy.]
<p>
[<em>Note:</em> If two <em>using-declarations</em> declare forwarding
constructors with the same parameter-type-lists, 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.  The base class constructor referred to in the
<em>mem-initializer</em> is called the constructor <em>forwarded
to</em>.
<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 type T and forward to all its constructors, while
writing a message to the standard log whenever such an object is destroyed.
</blockquote>
</body>
</html>