<html> 
	<style type="text/css">
<style type="text/css">

body { color: #000000; background-color: #FFFFFF; }
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5empadding-right: 0.5em; ; }

blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }

blockquote pre em { font-family: normal }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto; }
th { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }
td { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }

</style>
	</style>

<div style="text-align: right; float: right">
<p>ISO/IEC JTC1 SC22 WG21, Core Working Group<br>P0195R1<br>Robert Haberlach (rh633{at}cam{dot}ac.uk)<br>2016-10-16</p>
</div>
	
	<h2>Modernizing using-declarations</h2>
	
	<p><em>using-declaration</em>s should be able to cope with lists and pack expansions to allow flexible injection of names.</p>
	
	<h3>Motivation</h3>
	<p>With variadic templates having been introduced in C++11, many language constructs were updated to operate on pack expansions.
	Just as some situations require derivation from a pack of classes, some require introduction of a name from a pack of classes. Consider</p>
	
<pre class="extract">
template &lt;typename... T>
struct Overloader : /* [&hellip;] */ {
    // [&hellip;]
};

template &lt;typename... T>
constexpr auto make_overloader(T&&... t) {
    return Overloader&lt;T...>{std::forward&lt;T>(t)...};
}

int main() {
    auto o = make_overloader([] (auto const& a) {std::cout << a;},
                             [] (float f) {std::cout << std::setprecision(3) << f;});
}
</pre>
	<p>The implementation of <tt>Overloader</tt> is verbose and inefficient; One has to recursively introduce overloads of <tt>operator()</tt>:</p>
	
<pre class="extract">
template &lt;typename T, typename... Ts>
struct Overloader : T, Overloader&lt;Ts...> {
    using T::operator();
    using Overloader&lt;Ts...>::operator();
    // [&hellip;]
};

template &lt;typename T> struct Overloader&lt;T> : T {
    using T::operator();
};
</pre>
<p>While it's possible to achieve logarithmic instantiation depth, the resulting implementation
is needlessly complicated and still less efficient than the following, terse syntax:</p>

<pre class="extract">
template &lt;typename... Ts>
struct Overloader : Ts... {
    using Ts::operator()...;
    // [&hellip;]
};
</pre>

<h3>Design decisions and impact</h3>
<p>We propose that a <em>using-declaration</em> consist of a list of names, each called a <em>using-declarator</em>. 

As the proposed change is solely an enhancement, well-formed programs and their semantics are unaffected.</p>

	
	<h3>Proposed wording</h3>
	<p>Modify 3.3.2 [basic.scope.pdecl] &para;4 as indicated:</p>
	<blockquote class="std">The point of declaration of a <em>using-<del>declaration</del><ins>declarator</ins></em> that does not name a constructor is immediately after the
<em>using-<del>declaration</del><ins>declarator</ins></em> (7.3.3).</blockquote>
	
	<p>Modify 3.4.3.1 [class.qual] &para;2 (2.2) as indicated:</p>
	<blockquote class="std">&#8212; in <ins>a <em>using-declarator</em> of </ins>a <em>using-declaration</em> (7.3.3) that is a <em>member-declaration</em>, 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>&#8217;s <em>template-name</em> in the last component of the <em>nested-name-specifier</em>,</blockquote>
	
	<p>Modify 7.3.3 [namespace.udecl] &para;1 as indicated:</p>
	
	<blockquote class="std"><del>A <em>using-declaration</em> introduces a
set of declarations into the declarative region in which the
<em>using-declaration</em> appears.</del>
<pre>        <em>using-declaration</em>:
                <del>typename<sub><em>opt</em></sub> <em>nested-name-specifier unqualified-id</em></del>
                <ins>using <em>using-declarator-list</em>;</ins>
                
        <ins><em>using-declarator-list:</em></ins>
                <ins><em>using-declarator</em>...<sub><em>opt</em></sub></ins>
                <ins><em>using-declarator-list</em>, <em>using-declarator</em>...<sub><em>opt</em></sub></ins>
        
        <ins><em>using-declarator:</em></ins>
                <ins>typename<sub><em>opt</em></sub> <em>nested-name-specifier unqualified-id</em></ins>
	</pre>
	<p><ins>Each <em>using-declarator</em> in a
<em>using-declaration</em><sup>98</sup> introduces a set of declarations
into the declarative region in which the <em>using-declaration</em>
appears.</ins>
The set of declarations introduced by the <em>using-<del>declaration</del><ins>declarator</ins></em>
is found by performing qualified name lookup
(3.4.3, 10.2) for the name in the <em>using-<del>declaration</del><ins>declarator</ins></em>,
excluding functions that are hidden as described
below. If the <em>using-<del>declaration</del><ins>declarator</ins></em>
does not name a constructor, the <em>unqualified-id</em> is declared in the
declarative region in which the <em>using-declaration</em> appears as a synonym for
each declaration introduced by the <em>using-<del>declaration</del><ins>declarator</ins></em>.
[ <em>Note</em>: 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>&#8217;s declarative region.
&#8212; <em>end note</em> ]
If <del>the</del><ins>a</ins> <em>using-<del>declaration</del><ins>declarator</ins></em>
names a constructor, it declares that the class inherits the set of
constructor declarations introduced by the <em>using-declaration</em>
from the nominated base class.

<hr>
<ins><sup>98) A <em>using-declaration</em> with more than one <em>using-declarator</em> is equivalent to a corresponding sequence of
              <em>using-declaration</em>s with one <em>using-declarator</em>.
</sup></ins>
</blockquote>
	
	<p>Modify 7.3.3 [namespace.udecl] &para;3 as indicated:</p>
	<blockquote class="std">
		In a <em>using-declaration</em> used as a <em>member-declaration</em>, <del>the</del><ins>each <em>using-declarator</em>&#8217;s</ins> <em>nested-name-specifier</em> shall name a
		base class of the class being defined. If <del>such</del> a <em>using-<del>declaration</del><ins>declarator</ins></em> names a constructor,
	    <del>the</del><ins>its</ins> <em>nested-name-specifier</em> shall name a direct base class of the class being defined. <ins>[ <em>Example:</em>
<pre class="example">
template &lt;typename... bases>
struct X : bases... {
	using bases::g...;
};

X&lt;B, D> x; // OK: B::g and D::g introduced
</pre> &mdash; <em>end example</em> ]</ins>

	</blockquote>
	
	<p>Modify 7.3.3 [namespace.udecl] &para;10 as indicated:</p>
	<blockquote class="std">
	[<em>Example:</em> 
	<pre class="example">
namespace A {
    int i;
}

namespace A1 {
    <del>using A::i;</del>
    using A::i<ins>, A::i</ins>; // OK: double declaration
}
    
struct B {
    int i;
};

struct X : B {
    <del>using B::i;</del>
    using B::i<ins>, B::i</ins>; // error: double member declaration
};
	</pre>
	<em>&#8212; end example</em> ]
	</blockquote>
	<p>Modify 7.3.3 [namespace.udecl] &para;19 as indicated:</p>
	<blockquote class="std">If a <em>using-<del>declaration</del><ins>declarator</ins></em> uses the keyword <tt>typename</tt> and specifies a dependent name (14.6.2),
	the name introduced by the <em>using-declaration</em> is treated as a <em>typedef-name</em> (7.1.3).</blockquote>
	
	<p>Add a bullet (4.13) the list in 14.5.3 [temp.variadic] &para;4:</p>
	<blockquote class="stdins">&#8212; In a <em>using-declaration</em> (7.3.3); the pattern is a <em>using-declarator</em>.	</blockquote>

<h3>Acknowledgments</h3>
<p>Thanks to Daveed Vandevoorde for assistance in preparing the wording.</p>
</html>
