<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html> <head>
<title>US-65: Removing Inheriting Constructors</title>
<style type="text/css">
.ins {background-color:#A0FFA0}
.del {background-color:#FFA0A0; text-decoration: line-through;}
</style>
</head>

<body>
<h1>US-65: Removing Inheriting Constructors</h1>

<p>Author: Douglas Gregor<br>
Contact: doug.gregor@gmail.com<br>
Organization: Apple<br>
Date: 2011-02-28<br>
Number: N3258=11-0028</p>

<h2>Introduction</h2>

<p>This proposal recommends the removal of inheriting constructors
(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm">N2540</a>) from the C++0x working paper, per National Body comment
US-65. The author believes that inheriting constructors should be
considered as a feature for future language standards, but that
the risks associated with keeping this feature in the C++0x working
paper far outweigh the benefits.</p>

<p>Inheriting constructors should be removed from the C++0x working
paper for the following reasons:</p>

<ul>
  <li><b>Inheriting constructors are unimplemented</b>: Without
  implementation experience, we have no reasonable assurance that the
  feature is implementable in all compilers or can work as the authors
  intended. Implementing a feature is the only way to ensure that the
  specification is sound, and has always resulted in changes and
  improvements to the specification.</li>
  
  <li><b>Inheriting constructors have no user experience</b>: Since
  there are no implementations of this feature, there are no users and
  has been no feedback about usefulness of the feature. For example,
  we don't know whether the limitations of this feature (inability to
  provide initialization for other bases or members, inability to
  inherit constructors from a dependent base class) are too
  restrictive for real-world use,</li>

  <li><b>Inheriting constructors can be <ahref="#emulation">emulated</a>
  with variadic templates</b>: by
  using variadic templates, one can write a constructor that
  captures any arguments and forwards them to a base class,
  effectively inheriting that base class's constructors. The
  following section contains more information about the differences
  between such a forwarding constructor and inheriting
  constructors.</li>
  
  <li><b>The cost of removing inheriting constructors is low</b>:
  There is no code, no language wording, and no Standard Library
  construct that depends on inheriting constructors, and the wording
  for inheriting constructors is fairly self-contained, making the
  removal of this feature simple. Moreover, since this feature has not
  been implemented in the more than two years since it was accepted,
  it seems unlikely that removal will affect any National Body votes
  or the user community at large.</li>
</ul>

<h2 name="emulation">Emulating Inheriting Constructors with Variadic Templates</h2>

<p>One can emulate inheriting constructors using a catch-all variadic template that forwards all of its arguments. For example:</p>

<pre>
template&lt;typename Mixin&gt;
class add_color : public Mixin {
  Color color;

public:
  template&lt;typename ...Args&gt;
  add_color(Args &amp;&amp;...args)
    : Mixin(std::forward&lt;Args&gt;(args)...), color(Red) { }
};
</pre>

<p>There are several benefits to the variadic-template implementation for constructor forwarding:</p>

<ul>
  <li>Ability to initialize other base classes or members.</li>
  <li>Ability to make changes to the parameters before they are forwarded.</li>
  <li>Ability to add arbitrary code into the subclass's constructor.</li>
</ul>

<p>There are also several problems with the variadic-template implementation:</p>

<ul>
  <li>The variadic-template constructor overloads as a catch-all variadic template, rather than participating as the underlying set of base constructors.</li>
  
  <li>Non-type constructor characteristics such as <code>explicit</code> and <code>constexpr</code> are lost.</li>
</ul>

<p>The variadic-template implementation is clearly not a drop-in
replacement for inheriting constructors, and there are trade-offs in
both directions. Does that mean we need both features? Perhaps, but we
need usage experience to determine whether the inheriting-constructors
feature as specified has the right design tradeoffs. We may find that
the limitations of the feature as specified mean that the vast
majority of users will end up employing the variadic-template
implementation instead, in which case we'd likely want to change the
design of inheriting constructors. We need this usage experience prior
to standardization, not after standardization, and it becomes even
more important when we already have a partial solution to the
problem.</p>

<h2>Proposed Wording</h2>

<p>Modify 3.4.3.1 [class.qual]p2 as follows:</p>

<ol start="2">
  <li>In a lookup in which the constructor is an acceptable lookup result<span class="ins">,</span> <span class="del">and</span> the <i>nested-name-specifier</i> nominates a class <code>C</code><span class="del">:</span>

    <ul>
      <li><span class="del">if the name specified after the <i>nested-name-specifier</i>, when looked up in <code>C</code>, is the <i>injected-class-name</i> of C (Clause 9), or</span></li>
      <li><span class="del">in a <i>using-declaration</i> (7.3.3) that is a <i>member-declaration</i>, if the name specified after the <i>nested-name-specifier</i> is the same as the <i>identifier</i> or the <i>simple-template-id</i>'s <i>template-name</i> in the last component of the <i>nested-name-specifier</i>,</span></li>
      </ul>
      
      <span class="ins">, and the name specified after the <i>nested-name-specifier</i>, when looked up in <code>C</code>, is the <i>injected-class-name</i> of C (Clause 9), </span> the name is instead considered to name the constructor of class <code>C</code>. [ <i>Note</i>: for example, the constructor is not an acceptable lookup result in an <i>elaborated-type-specifier</i> so the constructor would not be used in place of the <i>injected-class-name</i>. -- <i>end note</i> ] Such a constructor name shall be used only in the <i>declarator-id</i> of a declaration that names a constructor<span class="del"> or in a <i>using-declaration</i></span>.</li>
</ol>

<p>Modify 7.3.3 [namespace.udecl] as follows:</p>

<ol start="1">
  <li>A <i>using-declaration</i> introduces a name into the declarative region in which the <i>using-declaration</i> appears. <span class="ins">That name is a synonym for the name of some entity declared elsewhere.</span>

  <pre>
<i>using-declaration</i>:
  using typename<sub>opt</sub> ::<sub>opt</sub> <i>nested-name-specifier</i> <i>unqualified-id</i> ;
  using :: <i>unqualified-id</i> ;
</pre>
  
The member name specified in a <i>using-declaration</i> is declared in the declarative region in which the using- declaration appears. [<i>Note</i>: only the specified name is so declared; specifying an enumeration name in a <i>using-declaration</i> does not declare its enumerators in the <i>using-declaration</i>'s declarative region. -- <i>end note</i>]
  <span class="del">If a <i>using-declaration</i> names a constructor (3.4.3.1), it implicitly declares a set of constructors in the class in which the <i>using-declaration</i> appears (12.9); otherwise the name specified in a <i>using-declaration</i> is a synonym for the name of some entity declared elsewhere.</span></li>

  <li>(No change to this paragraph)</li>

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

  <li>[<i>Note</i>: Since <span class="ins">constructors and</span> destructors do not have names, a <i>using-declaration</i> cannot refer to a <span class="ins">constructor or</span> 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 <i>using-declaration</i> specifies a conversion function (14.5.2). -- <i>end note</i> ]
</ol>

<ol start="15">
  <li>When a <i>using-declaration</i> 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, <i>parameter-type-list</i> (8.3.5), cv-qualification, and <i>ref-qualifier</i> (if any) in a base class (rather than conflicting). <span class="del">[ <i>Note</i>: For <i>using-declaration</i>s that name a constructor, see 12.9. -- <i>end note</i> ]</span></li>

  <li>(No change to this paragraph)</li>

  <li><span class="del">The access rules for inheriting constructors are specified in 12.9; otherwise all</span><span class="ins">All</span> instances of the name mentioned in a using-declaration shall be accessible. In particular, if a derived class uses a using-declaration 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. [...]</li>
  
  <li>The alias created by the <i>using-declaration</i> has the usual accessibility for a <i>member-declaration</i>. <span class="del">[<i>Note</i>: A <i>using-declaration</i> that names a constructor does not create aliases; see 12.9 for the pertinent accessibility rules. -- <i>end note</i>]</span> </li>
  
</ol>

<p>Remove section 12.9 [class.inhctor].</p>

<p>Note: we leave the change to 12.1 [class.ctor]p5, which was a small
clarification that does not have anything to do with inheriting
constructors.</p>

<hr>
<address></address>
<!-- hhmts start --> Last modified: Mon Feb 28 08:34:59 PST 2011 <!-- hhmts end -->
</body> </html>
