<!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>Implicit template parameters</title>
</head>

<body>
<p>N3601<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-17<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>Implicit template parameters</h1> 
<p>The purpose of this example is to eliminate the need for the redundant
<tt>template&lt;typename T, T t&gt;</tt> idiom. This idiom is widely used,
with  over 100k hits on Google.</p>
<p>The goal is to be able to replace a template declaration like
<tt>template&lt;typename T, T t&gt; struct C;</tt> with another declaration so
that we can instantatiate the template like <tt>C&lt;&amp;X::f&gt;</tt>
instead of having to say <tt>C&lt;decltype(&amp;X::f), &amp;X::f&gt;</tt>.</p>
<p>The basic idea is to be able to say <tt>template&lt;using typename T, T t&gt; struct C {/* ... */};</tt> to indicate that <tt>T</tt> 
should be deduced. To describe in more detail, we consider some extended examples
of template classes and functions.

<h2>Implicit template parameters for classes</h2>
<p>Consider a hypothetical compile-time
        reflection type trait <tt>describe_field</tt> that can give properties of a class member function.</p>
<code>struct A {
  void f(int i);
  double g(size_t s);
  int i;
};


<span class="comment">/* ... */</span>
cout &lt;&lt; describe_field&lt;<span class="comment">/* Something indicating we want a description of <tt>&amp;A::f</tt> */</span>&gt;::name; <span class="comment">  // Prints "f"</span>
cout &lt;&lt; describe_field&lt;<span class="comment">/* Something indicating we want a description of <tt>&amp;A::g</tt> */</span>&gt;::arity; <span class="comment">  // prints 1</span> </code>
<p>The question is "what should the declaration of <tt>describe_field</tt> look like?" Since <tt>describe_field</tt> takes 
    a non-type template parameter, we would probably use the familiar (100k hits on Google) 
		&ldquo;<tt style="white-space:nowrap">template&lt;class T, T t&gt;</tt>&rdquo; idiom
<code>template&lt;typename T, T t&gt; struct describe_field { <span class="comment">/* ... */</span> };
<span class="comment">/* ... */</span>
cout &lt;&lt; describe_field&lt;decltype(&amp;A::f), &amp;A::f&gt;::name; <span class="comment">  // Prints "f"</span>
cout &lt;&lt; describe_field&lt;decltype(&amp;A::g), &amp;A::g&gt;::arity; <span class="comment">  // prints 1</span> </code>
That is pretty ugly, and uglier examples are easier to construct.</p>
The key idea is that passing the type of the second template parameter is 
redundant information because it can be inferred using ordinary 
type deduction from the second type parameter. With that in mind, we propose 
that prefacing a template parameter with <tt>using</tt> indicates that
it should not be passed explicitly as a template argument but instead will be
deduced from subsequent non-type template arguments. This immediately allows
us to improve the usability of  <tt>describe_field</tt> as follows.
<code>template&lt;using typename T, T t&gt; struct describe_field { <span class="comment">/* ... */</span> };
<span class="comment">/* ... */</span>
cout &lt;&lt; describe_field&lt;&amp;A::f&gt;::name;   <span class="comment">// OK. T is void(A::*)(int)</span>
cout &lt;&lt; describe_field&lt;&amp;A::g&gt;::arity;  <span class="comment">// OK. T is double(A::*)(size_t)</span> </code>

<h2>Implicit template parameters for functions</h2>
Note that this proposal works identically for functions as well.
<code>template&lt;using typename T, T t&gt;
T f() { <span class="comment">/* ... */</span> };
int i = f&lt;7&gt;()<span class="comment"> // OK, T is int</span></code>
 <p>As a motivating example
for functions, we present a corrected version of an example from N3405 that now
makes it clear that we need to use implicit template parameters.
Code like the following is all too familiar:
<code>log &lt;&lt; "Getting ready to call Order::execute on " &lt;&lt; *this &lt;&lt; with arguments " 
    &lt;&lt; a1 &lt;&lt; ", " &lt;&lt; a2 &lt;&lt; endl;
auto result = execute(a1, a2);
log &lt;&lt; "Order::execute returned " &lt;&lt; result &lt;&lt; endl;
 </code></p>
 Here we define a wrapper function that can log calls to general methods at a callsite.
 (Note that this also leverages the putative <tt>describe_field</tt> template from above)
 <code><span class="comment">// Convenience function to variadically print to a stream</span>
template&lt;typename T, typename... Ts&gt;
void printArgs(ostream &amp;os, T&amp;&amp; t, Ts&amp;&amp;... ts) {
  os &lt;&lt; t &lt;&lt; ", ";
  printArgs(os, forward&lt;Ts&gt;(ts)...);
};
void printArgs(ostream &amp;os) {}

template&lt;using typename Ret; using typename Cls, using typename... ArgTypes, Ret(*c)(ArgTypes...)&gt;
typename result_of&lt;C(ArgTypes...)&gt;::type call_method_and_log ()(Cls *t, ArgsTypes&amp;&amp;... args) {
  log &lt;&lt; "Getting ready to call " &lt;&lt; describe_field&lt;m&gt;::name &lt;&lt; " with arguments ";
  printArgs(log, args...);
  Result result = t-&gt;*c(forward&lt;Args&gt;(args)...);
  log &lt;&lt; describe_field&lt;c&gt;::name &lt;&lt; " returned " &lt;&lt; result;
  return result;
}</code>
Now that's out of the way, we can replace the above example by:
<code>auto result = call_method_and_log&lt;&amp;A::f&gt;(this, a1, a2);
</code>
<p>This is not only simpler than the above, but it is less vulnerable to error
as in the original code, the caller would be likely to cut and paste the
&ldquo;Getting ready to call <span class="comment">...</span>&rdquo; boilerplate
and possibly getting the wrong name for the method. Using the 
&ldquo;<tt>template&lt;typename T, T t&gt;</tt>&rdquo; is very problematic as
it is not apparent how (or if) one can specify the signature:  
<code>template&lt;typename T, T t&gt;
<span class="comment">???</span> call_method_and_log(<span class="comment">???</span>);</code> 
<dl><dt>Note:</dt>
<dd>In n3405, the call was incorrectly written like <tt>call_method_and_log(&amp;A::f, this, a1, a2)</tt>,
which made it appear that the same behavior could be accomplished without
implicit parameter lists. However, that signature does not work because
then we could not of course have referred to 
<tt>describe_field&lt;c&gt;</tt> within <tt>call_method_and_log</tt>.
</dd></dl>
<h2>Specialization</h2>
<p>In addition to simplifying the use of <tt>describe_field</tt>, implicit
template parameters can also be used to simplify its implementation, which we
use here to illustrate some additional features of implicit template parameters.
<code>template&lt;using typename Ret, using class Cls, using typename... ArgTypes,  Ret(Cls::*t)(ArgTypes...)&gt;
struct describe_field {
  static char const *name = <span class="comment">/* Some compiler intrinsic */</span>;
  static size_t const arity = sizeof...(ArgTypes...);
  <span class="comment">/* ... */</span>
};
<span class="comment">/* ... */</span>
cout &lt;&lt; describe_field&lt;&amp;A::f&gt;::name;
cout &lt;&lt; describe_field&lt;&amp;A::g&gt;::arity;</code>
Of course, we might want to use <tt>describe_field</tt> to describe fields that
are not member functions. Because the parameters introduced with <tt>using</tt> do
not appear in the argument list, we can partially specialize on non-type parameters just
like we are used to doing with type parameters:
<code>template&lt;using typename T, T t&gt; struct describe_field;

template&lt;typename Ret, class Cls, typename... ArgTypes,  Ret(Cls::*t)(ArgTypes...)&gt;  <span class="comment">// Specialize on member function</span>
struct describe_field&lt;t&gt; { <span class="comment">/* As above */</span> };

template&lt;typename T, class Cls, Ret Cls::*t&gt;  <span class="comment">// Specialize on data member</span>
struct describe_field&lt;t&gt; {
  static char const *name = <span class="comment">/* Some compiler intrinsic */</span>;
  typedef T field_type; 
};
<span class="comment">/* ... */</span>
cout &lt;&lt; describe_field&lt;&amp;A::f&gt;::name;  <span class="comment">// OK. Matches partial specialization for member function</span>
cout &lt;&lt; describe_field&lt;&amp;A::g&gt;::arity;  <span class="comment">// OK. Matches partial specialization for member function</span>
cout &lt;&lt; describe_field&lt;&amp;A::i&gt;::name;  <span class="comment">// OK. Matches partial specialization for data member</span>
</code>
<h2>The deduction process</h2>
<p>Given a template definition of the form:
<code>template&lt;using <em>parameter-declaration_1</em>, ..., using <em>parameter-declaration_n</em>, <em>parameter-declaration-list</em>&gt; <em>declaration</em>;</code>
that declares a given identifier, we want to unambiguously instantiate <em>identifier</em>&lt;<em>template-argument-list</em>&gt;, where 
<em>template-argument-list</em> are valid arguments for <em>template-parameter-list</em>.</p>
<p>Let <em>non-type-parameter-list</em> be the the types of the <em>parameter-declaration-list</em> that
are non-type template parameters, and <em>type-parameter-list</em> be the remaining parameters. Let <em>non-type-argument-list</em> and
<em>type-argument-list</em> denote the corresponding arguments.</p>

<p>Now declare a function
<code>template&lt;<em>type-parameter-list</em>, <em>parameter-declaration_1</em>, ..., <em>parameter-declaration_n</em>&gt; void f(<em>non-type-parameter-list</em>);</code>
If the call <code>f&lt;type-argument-list&gt;(<em>non-type-argument-list</em>)</code> deduces
all of the <em>parameter-declaration_*</em> to a corresponding <em>argument_*</em>, then the original template's instantiation
exists and is the result of substituting <em>argument_*</em> for <em>parameter-declaration_*</em> 
and <em>template-argument-list</em> for <em>template-parameter-list</em> in the original
template definition.

<p>Let us illustrate with an example. Suppose we have the following declarations:
<code>template&lt;int i&gt; struct X { 
  int m() { return i; }
  double n(double d) { return i + sqrt(d); }
};

template&lt; using int i, using typename... Args, typename R, R (X&lt;i&gt;::*mp)(Args...)&gt; 
Res func(Args... args) { return X&lt;i&gt;(args...); }
<span class="comment">/* ... */</span>
cout &lt;&lt; func&lt;double, &amp;X&lt;3&gt;::n&gt;(16.0)</code>
<p>Now declare the function <tt>f</tt> as follows:
<code>template&lt;typename R, int i, typename... Args&gt;f(R (X&lt;i&gt;::*mp)(Args...));</code>
Since the call <tt>f&lt;double&gt;(&amp;X&lt;3&gt;::n);</tt> deduces <tt>i==3</tt>
and <tt>Args...</tt> is <tt>double</tt> (try it!), we conclude
<tt>func&lt;double, &amp;X&lt;3&gt;::n&gt;(16.0)</tt> is <tt>7.0</tt>.</p>

</body></html>