<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  <style type="text/css">

.comment { color: #999999; font-style: italic; }
.pre { color: #000099; }
.string { color: #009900; }
.char { color: #009900; }
.float { color: #996600; }
.int { color: #999900; }
.bool { color: #000000; font-weight: bold; }
.type { color: #FF6633; }
.flow { color: #FF0000; }
.keyword { color: #990000; }
.operator { color: #663300; font-weight: bold; }
.operator { color: #663300; font-weight: bold; }
pre.code {
    border: 2px solid #666;
    background-color: #F4F4F4;
    padding-left: 10px;
    padding-top: 0px;
}
code {
    border: 2px solid #d0d0d0;
    background-color: LightYellow;
    padding: 2px;
    padding-left: 10px;
    display:table;
    white-space:pre;
    margin:2px;
    margin-bottom:10px;
}
dt {
    font-weight: bold;
}
.ins {
    background-color:#A0FFA0;
}
.del {
    background-color:#FFA0A0;
    text-decoration:line-through
}    
</style>

<title>Template parameter deduction for constructors</title>
</head>

<body>
<p>N3602<br/>
Revision of a section of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3405.html">N3405=12-0095</a><br>
2013-03-14<br/>
Mike Spertus, Symantec<br/>
<a href="mailto:mike_spertus@symantec.com">mike_spertus@symantec.com</a><br/>
Daveed Vandevoorde, Edison Design Group<br/>
<a href="mailto:daveed@edg.com">daveed@edg.com</a><br/>
<br/></p>

<h1>Template parameter deduction for constructors</h1> 
    <p>
			 This paper proposes extending template parameter deduction for functions
			 to constructors of template classes. The clearest way to describe
			 the problem and solution is with some examples.</p><p>Suppose we have
			 defined the following.

<code>vector&lt;int&gt; vi1 = { 0, 1, 1, 2, 3, 5, 8 };
vector&lt;int&gt; vi2;
template&lt;class Func&gt;
class Foo() { 
public: 
    Foo(Func f) : func(f) {} 
    void operator()(int i) { 
      os &lt;&lt; "Calling with " &lt;&lt; i &lt;&lt; endl;
      f(i); 
    } 
private: 
    Func func; 
};</code>

Currently, if we want to instantiate template classes, we need to either
specify the template parameters or use a "make_*" wrapper, leverage template
parameter deduction for functions, or punt completely:

<code>pair&lt;int, double&gt; p(2, 4.5);
auto t = make_tuple(4, 3, 2.5);
copy_n(vi1, 3, back_inserter(vi2));
<span class="comment">// Virtually impossible to pass a lambda to a template class' constructor</span>
for_each(vi.begin(), vi.end(), Foo&lt;<span class="comment">???</span>&gt;([&amp;](int i) { <span class="comment">...</span>}));
</code>

There are several problems with the above code:
</p><ul>

<li>Creating &#8220;make functions&#8221; like <tt>make_tuple</tt> is confusing,
artificial, extra boilerplate, and inconsistent with how non-template classes are constructed.</li>

<li>Since the standard library doesn't follow any consistent convention for
make functions, users have to scurry through documentation to find they need to
use <tt>make_tuple</tt> for <tt>tuple</tt>s
and <tt>back_inserter</tt> for <tt>back_insert_iterator</tt>s. Of course their own
template classes might not be as consistent or thoroughly-documented as the standard.</li>

<li>Specifying template parameters as in <tt>pair&lt;int, double&gt;(2, 4.5)</tt>
should be unnecessary since they can be inferred from the type of the arguments, as is
usual with template functions (this is the reason the standard provides make functions
for many template classes in the first place!).

</li><li>If we don't have a make function, we may not be able to
create class objects at all as indicated by the <tt><span class="comment">???</span></tt>
in the code above.</li>
</ul>

If we allowed the compiler to deduce the template parameters for constructors of
template classes, we could replace the above with:

<code>pair p(2, 4.5);
tuple t(4, 3, 2.5);
copy_n(vi1, 3, back_insert_iterator(vi2));
for_each(vi.begin(), vi.end(), Foo([&amp;](int i) { <span class="comment">...</span>})); <span class="comment">// Now easy to do</span>
</code>

We believe this is more consistent and simpler for both users and writers of
template classes, especially if we were using user-defined classes that might
not have carefully designed and documented make functions like <tt>pair</tt>,
<tt>tuple</tt>, and <tt>back_insert_iterator</tt>.

<h2>The Deduction Process</h2>
<p>We propose to allow a template name referring to a class template as a
simple-type-specifier in two contexts:
</p><ul>

  <li>Functional-notation simple type conversions ([expr.type.conv], and</li>
  <li>Simple-declarations of the form
      "<i>decl-specifier-seq id-expression initializer</i>".</li>
</ul>
<p>
In the case of
a function-notation type conversion (e.g., "<tt>tuple(1, 2.0, false)</tt>") or
a direct parenthesized or braced initialization,
the initialization is resolved as follows.
First, constructors and constructor templates declared in the named template
are enumerated.  Let Ci be such a constructor or constructor template;
together they form an overload set.  A parallel overload set <i>F</i> of
function templates is then created as follows:

For each Ci a function template is constructed with template parameters that
include both those of the named class template and if Ci is a constructor
template, those of that template (default arguments are included too) --
the function parameters are the constructor parameters, and the return type
is <tt>void</tt>

Deduction and overload resolution is then performed for a synthesized call
to <i>F</i> with the parenthesized or braced expressions used as arguments.
If that call doesn't yield a "best viable function", the program is ill-formed.
Otherwise, the template name is treated as the class-name that is obtained
from the named class template with the deduced arguments corresponding to that
template's parameters.
</p>
<p>
Let's look at an example:
<code>template&lt;typename T&gt; struct S {
  template&lt;typename U&gt; struct N {
    N(T);
    N(T, U);
    template&lt;typename V&gt; N(V, U);
  };
};

S&lt;int&gt;::N x{2.0, 1};
</code>

In this example, "<tt>S&lt;int&gt;::N</tt>" in the declaration of <tt>x</tt>
is missing template arguments, so the approach above kicks in.
Template arguments can only be left out this way from the "type" of the
declaration, but not from any name qualifiers used in naming the template;
i.e., we couldn't replace "<tt>S&lt;int&gt;::N</tt>" by just "<tt>S::N</tt>"
using some sort of additional level of deduction.
To deduce the initialized type, the compiler now creates an overload set as
follows:

<code>
    template&lt;typename U&gt; void <i>F</i>(S&lt;int&gt;::N&lt;U&gt; const&amp;);
    template&lt;typename U&gt; void <i>F</i>(S&lt;int&gt;::N&lt;U&gt; &amp;&amp;);
    template&lt;typename U&gt; void <i>F</i>(int);
    template&lt;typename U&gt; void <i>F</i>(int, U);
    template&lt;typename U, typename V&gt; void <i>F</i>(V, U);
</code>

(The first two candidates correspond to the implicitly-declared copy and move
contructors. Note that template parameter <tt>T</tt> is already known to
be <tt>int</tt> and is not a template parameter in the synthesized overload
set.)

Then the compiler performs overload resolution for a call "<tt><i>F</i>(2.0, 1)</tt>" 
which in this case finds a unique best candidate in the last synthesized function
with <tt>U = int</tt> and <tt>V = double</tt>.  The initialization
is therefore treated as "<tt>S&lt;int&gt;::N&lt;int&gt; x{2.0, 1};</tt>"
</p>



<p>
Note that after the deduction process described above the initialization may
still end up being ill-formed.  For example, a selected constructor might be
inaccessible or deleted, or the selected template instance might have been
specialized or partially specialized in such a way that the candidate
constructors will not match the initializer.
</p>

The case of a simple-declaration with copy-initialization syntax is treated
similarly to the approach described above, except that explicit constructors
and constructor templates are ignored, and the initializer expression is
used as the single call argument during the deduction process.

</body></html>