﻿<!DOCTYPE HTML>
<!-- saved from url=(0049)http://bekenn.github.io/isocpp/template-auto.html -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><HTML><HEAD><META 
content="IE=11.0000" http-equiv="X-UA-Compatible">
 
<META http-equiv="Content-Language" content="en-us"> 
<META http-equiv="Content-Type" content="text/html; charset=utf-8"> 
<TITLE>Declaring non-type template arguments with auto</TITLE> 
<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; }

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; }

table.frontmatter { border: 0;  margin: 0; }

ul.dash { list-style-type: none; }
ul.dash li:before { content: '\2014'; margin-left: -1em }

</STYLE>
 
<SCRIPT src="template-auto_files/run_prettify.js" type="text/javascript"></SCRIPT>
 
<META name="GENERATOR" content="MSHTML 11.00.9600.17963"></HEAD> 
<BODY>
<H1>Declaring non-type template arguments with <CODE 
class="prettyprint">auto</CODE></H1>
<TABLE width="619" class="frontmatter" style="border-collapse: collapse;" 
border="0" cellspacing="0" cellpadding="0">
  <TBODY>
  <TR>
    <TD align="left" valign="top">Document number:</TD>
    <TD>P0127R0</TD></TR>
  <TR>
    <TD align="left" valign="top">Date:</TD>
    <TD>2015-09-25</TD></TR>
  <TR>
    <TD align="left" valign="top">Project:</TD>
    <TD>Programming Language C++, Evolution Working Group</TD></TR>
  <TR>
    <TD align="left" valign="top">Revises:</TD>
    <TD><A href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4469.html">N4469</A></TD></TR>
  <TR>
    <TD align="left" valign="top">Reply-to:</TD>
    <TD>James Touton &lt;<A 
      href="mailto:bekenn@gmail.com">bekenn@gmail.com</A>&gt;</TD></TR></TBODY></TABLE>
<H2><A id="TableOfContents">Table of Contents</A></H2>
<OL>
  <LI><A href="http://bekenn.github.io/isocpp/template-auto.html#TableOfContents">Table 
  of Contents</A></LI>
  <LI><A 
  href="http://bekenn.github.io/isocpp/template-auto.html#Introduction">Introduction</A></LI>
  <LI><A href="http://bekenn.github.io/isocpp/template-auto.html#MotivationAndScope">Motivation 
  and Scope</A></LI>
  <LI><A href="http://bekenn.github.io/isocpp/template-auto.html#ImpactOnTheStandard">Impact 
  On the Standard</A></LI>
  <LI><A href="http://bekenn.github.io/isocpp/template-auto.html#DesignDecisions">Design 
  Decisions</A></LI>
  <LI><A href="http://bekenn.github.io/isocpp/template-auto.html#TechnicalSpecifications">Technical 
  Specifications</A></LI>
  <LI><A 
  href="http://bekenn.github.io/isocpp/template-auto.html#Wording">Wording</A></LI>
  <LI><A href="http://bekenn.github.io/isocpp/template-auto.html#Acknowledgments">Acknowledgments</A></LI></OL>
<H2><A id="Introduction">Introduction</A></H2>
<P>This paper proposes allowing non-type template parameters to be declared with 
the <CODE>auto</CODE> placeholder type specifier. The desired effect is that the 
type of the corresponding non-type template argument be automatically deduced, 
much like similar syntax works for polymorphic lambdas. This more focused 
proposal follows EWG's recommendations from the Spring 2015 Lenexa meeting.</P>
<P>The existing workaround is that the type of a non-type template parameter 
must be explicitly specified, which leads to unnecessary verbosity and reduced 
flexibility when writing a template intended to take constant arguments of any 
type. Example:</P>
<PRE class="example"><CODE class="prettyprint">template &lt;typename T, T v&gt; struct S { };    // <EM>definition</EM>
S&lt;decltype(x), x&gt; s;                    // <EM>instantiation</EM></CODE>
</PRE>
<P>The example makes use of <CODE class="prettyprint">decltype</CODE> to 
retrieve the type of <CODE>x</CODE> (a compile-time constant) before passing 
both the type and the value of <CODE>x</CODE> to <CODE>S</CODE>. The goal is to 
be able to modify the declaration of <CODE>S</CODE> such that the type of 
<CODE>x</CODE> doesn't need to be passed as a separate template argument, 
resulting in this simpler instantiation:</P>
<PRE class="example"><CODE class="prettyprint">S&lt;x&gt; s; // <EM>desired instantiation</EM></CODE>
</PRE>
<P>This can be achieved by allowing use of the <CODE 
class="prettyprint">auto</CODE> keyword in template parameter lists.</P>
<PRE class="example"><CODE class="prettyprint">template &lt;auto v&gt; struct S;                 // <EM>type of v is deduced</EM></CODE>
</PRE>
<H2><A id="MotivationAndScope">Motivation and Scope</A></H2>
<P>Consider a generic function call logger for an application that provides 
callback function pointers to a library. The logger should print the name of the 
function, the argument values, and the result of a call to any callback. In 
order to avoid calling the logger from within a callback function (and thus 
having to modify each function to support the logger), the logger itself is 
passed to the library in place of the callback function, and the logger passes 
the arguments along to the callback function. This implies that the logger for a 
callback function must match the callback function's type so that the library 
can call it directly.</P>
<P>It is desirable that the instantiation syntax for the logger be simple; the 
following seems perfectly reasonable:</P>
<PRE class="example"><CODE class="prettyprint">// <EM>can't specify string literals as template arguments, so provide a character array instead</EM>
static constexpr char cbname[] = "my_callback";
void initialize()
{
    library::register_callback(logger&lt;my_callback, cbname&gt;);
}</CODE>
</PRE>
<P>In order for this to work, <CODE>logger</CODE> must be a template that takes 
a function pointer and a character pointer as arguments. If the type of the 
function is fixed, this is no problem:</P>
<PRE class="example"><CODE class="prettyprint">// <EM>log any function with the signature int(int)</EM>
template &lt;int (* f)(int), const char* name&gt;
int logger(int arg)
{
    cout &lt;&lt; name &lt;&lt; '(' &lt;&lt; arg &lt;&lt; ')';
    int result = f(arg);
    cout &lt;&lt; " -&gt; " &lt;&lt; result &lt;&lt; endl;
    return result;
}</CODE>
</PRE>
<P>If the type of the function is not fixed, things get more complicated:</P>
<PRE class="example"><CODE class="prettyprint">// <EM>log each argument in a comma-separated list</EM>
template &lt;class... Args&gt; void log_args(Args... args);

// <EM>struct template that accepts a function pointer and a name</EM>
template &lt;class F, F f, const char* name&gt; struct fn_logger;

// <EM>use partial specialization to constrain f</EM>
// <EM>note that a second specialization would be needed to support functions returning void</EM>
template &lt;class R, class... Args, R (* f)(Args...), const char* name&gt;
struct fn_logger&lt;R (*)(Args...), f, name&gt;
{
    // <EM>call f, logging arguments and result</EM>
    static R call(Args... args)
    {
        cout &lt;&lt; name &lt;&lt; '(';
        log_args(args...);
        cout &lt;&lt; ')';
        auto result = f(args...);
        cout &lt;&lt; " -&gt; " &lt;&lt; result &lt;&lt; endl;
        return result;
    }
};

// <EM>variable template to simplify use of fn_logger</EM>
template &lt;class F, F f, const char* name&gt; constexpr auto logger = fn_logger&lt;F, f, name&gt;::call;</CODE>
</PRE>
<P>The instantiation syntax also gets more complicated, because the type of the 
function must be passed as an additional argument:</P>
<PRE class="example"><CODE class="prettyprint">// <EM>can't specify string literals as template arguments, so provide a character array instead</EM>
static constexpr char cbname[] = "my_callback";
void initialize()
{
    library::register_callback(decltype(&amp;my_callback), logger&lt;my_callback, cbname&gt;);
}</CODE>
</PRE>
<H3>Using <CODE class="prettyprint">auto</CODE></H3>
<P>The template parameter list syntax can be extended in a simple and natural 
way using the <CODE class="prettyprint">auto</CODE> keyword to indicate that the 
type of a value parameter is deduced at the point of instantiation:</P>
<PRE class="example"><CODE class="prettyprint">template &lt;auto x&gt; constexpr auto constant = x;

auto v1 = constant&lt;5&gt;;      // <EM>v1 == 5, decltype(v1) is int</EM>
auto v2 = constant&lt;true&gt;;   // <EM>v2 == true, decltype(v2) is bool</EM>
auto v3 = constant&lt;'a'&gt;;    // <EM>v3 == 'a', decltype(v3) is char</EM></CODE>
</PRE>
<P>The usual type modifiers may be used to constrain the type of the value 
parameter without the use of partial specialization:</P>
<PRE class="example"><CODE class="prettyprint">// <EM>p must be a pointer to const something</EM>
template &lt;const auto* p&gt; struct S;</CODE>
</PRE>
<P>Partial specialization may be used to switch on the type of a value 
parameter:</P>
<PRE class="example"><CODE class="prettyprint">template &lt;auto x&gt; struct S;
template &lt;int n&gt;
struct S&lt;n&gt;
{
    const char* type_name = "int";
};</CODE>
</PRE>
<P>Here is what the logger would look like using <CODE 
class="prettyprint">auto</CODE>:</P>
<PRE class="example"><CODE class="prettyprint">// <EM>log each argument in a comma-separated list</EM>
template &lt;class... Args&gt; void log_args(Args... args);

// <EM>struct template that accepts a function pointer and a name</EM>
template &lt;auto f, const char* name&gt; struct fn_logger;

// <EM>use partial specialization to constrain f</EM>
// <EM>note that a second specialization would be needed to support functions returning void</EM>
template &lt;class R, class... Args, R (* f)(Args...), const char* name&gt;
struct fn_logger&lt;f, name&gt;
{
    // <EM>call f, logging arguments and result</EM>
    static R call(Args... args)
    {
        cout &lt;&lt; name &lt;&lt; '(';
        log_args(args...);
        cout &lt;&lt; ')';
        auto result = f(args...);
        cout &lt;&lt; " -&gt; " &lt;&lt; result &lt;&lt; endl;
        return result;
    }
};

// <EM>variable template to simplify use of fn_logger</EM>
template &lt;auto f, const char* name&gt; constexpr auto logger = fn_logger&lt;f, name&gt;::call;</CODE>
</PRE>
<P>The function type no longer needs to be explicitly specified, which means the 
instantiation can go back to the desired form:</P>
<PRE class="example"><CODE class="prettyprint">library::register_callback(logger&lt;my_callback, cbname&gt;);</CODE>
</PRE>
<H3>As variadic template parameters</H3>
<P>When <CODE class="prettyprint">auto</CODE> appears as the type specifier for 
a parameter pack, it signifies that the type for each corresponding argument 
should be independently deduced:</P>
<PRE class="example"><CODE class="prettyprint">// <EM>List of heterogeneous constant values</EM>
// <EM>same as template &lt;auto v1, auto v2, auto v3, ...&gt;</EM>
template &lt;auto... vs&gt; struct value_list { };

// <EM>Retrieve the nth value in a list of values</EM>
template &lt;size_t n, auto... vs&gt; struct nth_value;
template &lt;size_t n, auto v1, auto... vs&gt;
struct nth_value&lt;n, v1, vs...&gt;
{
    static constexpr auto value = nth_value&lt;n - 1, vs...&gt;::value;
};
template &lt;auto v1, auto... vs&gt;
struct nth_value&lt;0, v1, vs...&gt;
{
    static constexpr auto value = v1;
};</CODE>
</PRE>
<P>A list of homogeneous constant values can be constructed with the aid of 
<CODE class="prettyprint">decltype</CODE>:</P>
<PRE class="example"><CODE class="prettyprint">// <EM>List of homogeneous constant values</EM>
template &lt;auto v1, decltype(v1)... vs&gt; struct typed_value_list { };</CODE>
</PRE>
<H2><A id="ImpactOnTheStandard">Impact On the Standard</A></H2>
<P>The proposed feature adds no keywords and does not change the meaning of any 
existing code.</P>
<H3>Opportunity cost</H3>
<P>There is an opportunity cost associated with adopting this particular meaning 
for the <CODE class="prettyprint">auto</CODE> keyword in this context. It has 
been suggested that <CODE class="prettyprint">auto</CODE> could be used to allow 
for template parameters accepting <EM>any kind</EM> of template argument, be it 
a type, a value, a template, or any other construct that templates may accept at 
any point in the future.</P>
<P>Such a feature is desirable, but the use of the <CODE 
class="prettyprint">auto</CODE> keyword for it is not. There is no existing 
context in which <CODE class="prettyprint">auto</CODE> acts as anything other 
than a stand-in for a type name; consistency with the rest of the language 
dictates that <CODE class="prettyprint">auto</CODE> behave as spelled out in 
this paper.</P>
<H2><A id="DesignDecisions">Design Decisions</A></H2>
<P>A few people have suggested that all values in a parameter pack introduced by 
<CODE class="prettyprint">auto</CODE> should have the same type. The rationale 
seems to be that because <CODE class="prettyprint">auto</CODE> can be replaced 
by a single type name in a multiple variable definition, the same should be true 
here:</P>
<PRE class="example"><CODE class="prettyprint">
auto x = 3.5, y = "hello";  // <EM>error, x and y must have the same type</EM></CODE>
</PRE>
<P>This approach is comparatively inflexible, in that it does not allow variadic 
lists of heterogeneous values. Additionally, the behavior specified in this 
document mirrors the existing behavior of the <CODE 
class="prettyprint">typename</CODE> and <CODE class="prettyprint">class</CODE> 
keywords in this context:</P>
<PRE class="example"><CODE class="prettyprint">// <EM>same as template &lt;typename T1, typename T2, typename T3, ...&gt;</EM>
template &lt;typename... Ts&gt; struct type_list { };

// <EM>same as template &lt;auto v1, auto v2, auto v3, ...&gt;</EM>
template &lt;auto... vs&gt; struct value_list { };</CODE>
</PRE>
<H2><A id="TechnicalSpecifications">Technical Specifications</A></H2>
<UL>
  <LI>The <CODE class="prettyprint">auto</CODE> keyword, when it appears in a 
  template parameter list, signifies that the associated template parameter is a 
  value parameter and that the type of the value parameter is to be deduced at 
  the point of template instantiation.</LI>
  <LI>The <CODE class="prettyprint">auto</CODE> keyword, when it introduces a 
  template parameter pack, signifies that each element in the parameter pack is 
  a value parameter and that the types of the value parameters are to be 
  independently deduced at the point of template instantiation.</LI>
  <LI>Type deduction for template parameters introduced with the <CODE class="prettyprint">auto</CODE> 
  keyword follows the same rules as specified for function template argument 
  type deduction.</LI></UL>
<H2><A id="Wording">Wording</A></H2>
<P>All modifications are presented relative to N4296.</P>
<P>Modify §7.1.6.4 [dcl.spec.auto] paragraph 5:</P>
<BLOCKQUOTE class="std">
  <P>A placeholder type can also be used in declaring a variable in the 
  <VAR>condition</VAR> of a selection statement (6.4) or an iteration statement 
  (6.5), in the <VAR>type-specifier-seq</VAR> in the <VAR>new-type-id</VAR> or 
  <VAR>type-id</VAR> of a <VAR>new-expression</VAR> (5.3.4), in a 
  <VAR>for-range-declaration</VAR>, <DEL>and </DEL>in declaring a static data 
  member with a brace-or-equal-initializer that appears within the 
  member-specification of a class definition (9.4.2)<INS>, and in the 
  <VAR>decl-specifier-seq</VAR> in the <VAR>parameter-declaration</VAR> of a 
  <VAR>template-parameter</VAR> (14.1)</INS>.</P></BLOCKQUOTE>
<P>Modify §14.1 [temp.param] paragraph 4:</P>
<BLOCKQUOTE class="std">
  <P>A non-type <VAR>template-parameter</VAR> shall have one of the following 
  (optionally <VAR>cv-qualified</VAR>) types:</P>
  <UL class="dash">
    <LI>integral or enumeration type,</LI>
    <LI>pointer to object or pointer to function,</LI>
    <LI>lvalue reference to object or lvalue reference to function,</LI>
    <LI>pointer to member,</LI>
    <LI><CODE>std::nullptr_t</CODE><DEL>.</DEL><INS>,</INS></LI>
    <LI><INS>a type that contains a placeholder type designated by 
    <CODE>auto</CODE> (7.1.6.4).</INS></LI></UL></BLOCKQUOTE>
<P>Modify §14.3.2 [temp.arg.nontype] paragraph 1:</P>
<BLOCKQUOTE class="std">
  <P>A <VAR>template-argument</VAR> for a non-type <VAR>template-parameter</VAR> 
  shall be a converted constant expression (5.20) of the type of the 
  <VAR>template-parameter</VAR>. <INS>If the type of the 
  <VAR>template-parameter</VAR> contains a placeholder type (7.1.6.4, 14.1), the 
  deduced parameter type is determined from the type of the 
  <VAR>template-argument</VAR> using the rules for template argument deduction 
  from a function call (14.8.2.1). If a deduced parameter type is not permitted 
  for a <VAR>template-parameter</VAR> declaration (14.1), the program is 
  ill-formed.</INS> For a non-type <VAR>template-parameter</VAR> of reference or 
  pointer type, the value of the constant expression shall not refer to (or for 
  a pointer type, shall not be the address of):</P>
  <UL class="dash">
    <LI>a subobject (1.8),</LI>
    <LI>a temporary object (12.2),</LI>
    <LI>a string literal (2.13.5),</LI>
    <LI>the result of a <CODE>typeid</CODE> expression (5.2.8), or</LI>
    <LI>a predefined <CODE>__func__</CODE> variable (8.4.1).</LI></UL>
  <P>[&nbsp;<I>Note:</I> If the <VAR>template-argument</VAR> represents a set of 
  overloaded functions (or a pointer or member pointer to such), the matching 
  function is selected from the set (13.4). —<I>end 
note</I>&nbsp;]</P></BLOCKQUOTE>
<P>Modify §14.3.2 [temp.arg.nontype] paragraph 2:</P>
<BLOCKQUOTE class="std">
  <P>[&nbsp;<I>Example:</I></P>
<PRE class="example"><CODE>template&lt;const int* pci&gt; struct X { /* <EM>...</EM> */ };
int ai[10];
X&lt;ai&gt; xi; // <EM>array to pointer and qualification conversions</EM>

struct Y { /* <EM>...</EM> */ };
template&lt;const Y&amp; b&gt; struct Z { /* <EM>...</EM> */ };
Y y;
Z&lt;y&gt; z; // <EM>no conversion, but note extra cv-qualification</EM>

template&lt;int (&amp;pa)[5]&gt; struct W { /* <EM>...</EM> */ };
int b[5];
W&lt;b&gt; w; // <EM>no conversion</EM>

void f(char);
void f(int);

template&lt;void (*pf)(int)&gt; struct A { /* <EM>...</EM> */ };
A&lt;&amp;f&gt; a; // <EM>selects f(int)</EM>
<INS>
template&lt;auto n&gt; struct B { /* <EM>...</EM> */ };
B&lt;5&gt; b1;   // <EM>OK: template parameter type is int</EM>
B&lt;'a'&gt; b2; // <EM>OK: template parameter type is char</EM>
B&lt;2.5&gt; b3; // <EM>error: template parameter type cannot be double</EM></INS></CODE>
</PRE>
  <P>—<I>end example</I>&nbsp;]</P></BLOCKQUOTE>
<P>Modify §14.5.5 [temp.class.spec] paragraph 8 list item 8.2:</P>
<BLOCKQUOTE class="std">
  <P>The type of a template parameter corresponding to a specialized non-type 
  argument shall not be dependent on a parameter of the specialization<INS> that 
  appears as a (possibly cv-qualified) argument in the argument list of the 
  specialization. Otherwise, the corresponding arguments are deduced from the 
  type of the non-type argument</INS>. [&nbsp;<I>Example:</I></P>
<PRE class="example"><CODE>template &lt;class T, T t&gt; struct C {};
template &lt;class T&gt; struct C&lt;T, 1&gt;;                  // <EM>error</EM>
template&lt; int X, int (*array_ptr)[X] &gt; class A {};
int array[5];
template&lt; int X &gt; class A&lt;X,&amp;array&gt; { };            // <EM>error</EM>
<INS>template &lt;auto f&gt; class B {};
template &lt;class R, class... Args, R (* f)(Args...)&gt; class B&lt;f&gt; {} // <EM>ok</EM></INS></CODE>
</PRE>
  <P>—<I>end example</I>&nbsp;]</P></BLOCKQUOTE>
<P>Modify §14.6.2.2 [temp.dep.expr] paragraph 3:</P>
<BLOCKQUOTE class="std">
  <P>An <VAR>id-expression</VAR> is type-dependent if it contains</P>
  <UL class="dash">
    <LI>an <VAR>identifier</VAR> associated by name lookup with one or more 
    declarations declared with a dependent type,</LI>
    <LI><INS>an <VAR>identifier</VAR> associated by name lookup with a non-type 
    <VAR>template-parameter</VAR> declared with a type that contains a 
    placeholder type (7.1.6.4),</INS></LI>
    <LI>an <VAR>identifier</VAR> associated by name lookup with one or more 
    declarations of member functions of the current instantiation declared with 
    a return type that contains a placeholder type<DEL> (7.1.6.4)</DEL>,</LI>
    <LI>the <VAR>identifier</VAR> <CODE>__func__</CODE> (8.4.1), where any 
    enclosing function is a template, a member of a class template, or a generic 
    lambda,</LI>
    <LI>a <VAR>template-id</VAR> that is dependent,</LI>
    <LI>a <VAR>conversion-function-id</VAR> that specifies a dependent type, 
    or</LI>
    <LI>a <VAR>nested-name-specifier</VAR> or a <VAR>qualified-id</VAR> that 
    names a member of an unknown specialization;</LI></UL>
  <P>or if it names a dependent member of the current instantiation that is a 
  static data member of type “array of unknown bound of T” for some T 
  (14.5.1.3). Expressions of the following forms are type-dependent only if the 
  type specified by the <VAR>type-id</VAR>, <VAR>simple-type-specifier</VAR> or 
  <VAR>new-type-id</VAR> is dependent, even if any subexpression is 
  type-dependent:</P>
  <DL>
    <DD><VAR>simple-type-specifier</VAR> <CODE>(</CODE> 
    <VAR>expression-list<SUB>opt</SUB></VAR> <CODE>)</CODE></DD>
    <DD><CODE>::</CODE><VAR><SUB>opt</SUB></VAR> <CODE>new</CODE> 
    <VAR>new-placement<SUB>opt</SUB></VAR> <VAR>new-type-id</VAR> 
    <VAR>new-initializer<SUB>opt</SUB></VAR></DD>
    <DD><CODE>::</CODE><VAR><SUB>opt</SUB></VAR> <CODE>new</CODE> 
    <VAR>new-placement<SUB>opt</SUB></VAR> <CODE>(</CODE> <VAR>type-id</VAR> 
    <CODE>)</CODE> <VAR>new-initializer<SUB>opt</SUB></VAR></DD>
    <DD><CODE>dynamic_cast</CODE> <CODE>&lt;</CODE> <VAR>type-id</VAR> 
    <CODE>&gt;</CODE> <CODE>(</CODE> <VAR>expression</VAR> <CODE>)</CODE></DD>
    <DD><CODE>static_cast</CODE> <CODE>&lt;</CODE> <VAR>type-id</VAR> 
    <CODE>&gt;</CODE> <CODE>(</CODE> <VAR>expression</VAR> <CODE>)</CODE></DD>
    <DD><CODE>const_cast</CODE> <CODE>&lt;</CODE> <VAR>type-id</VAR> 
    <CODE>&gt;</CODE> <CODE>(</CODE> <VAR>expression</VAR> <CODE>)</CODE></DD>
    <DD><CODE>reinterpret_cast</CODE> <CODE>&lt;</CODE> <VAR>type-id</VAR> 
    <CODE>&gt;</CODE> <CODE>(</CODE> <VAR>expression</VAR> <CODE>)</CODE></DD>
    <DD><CODE>(</CODE> <VAR>type-id</VAR> <CODE>)</CODE> 
    <VAR>cast-expression</VAR></DD></DL></BLOCKQUOTE>
<P>Modify §14.8.2.5 [temp.deduct.type] paragraph 3:</P>
<BLOCKQUOTE class="std">
  <P>The non-deduced contexts are:</P>
  <UL class="dash">
    <LI>The <VAR>nested-name-specifier</VAR> of a type that was specified using 
    a <VAR>qualified-id</VAR>.</LI>
    <LI>The <VAR>expression</VAR> of a <VAR>decltype-specifier</VAR>.</LI>
    <LI>A non-type template argument or an array bound in which a subexpression 
    references a template parameter. <INS>[&nbsp;<I>Note:</I> Deduction is still 
    performed based on the type of a non-type template argument. —<I>end 
    note</I>&nbsp;]</INS></LI>
    <LI>A template parameter used in the parameter type of a function parameter 
    that has a default argument that is being used in the call for which 
    argument deduction is being done.</LI>
    <LI>A function parameter for which argument deduction cannot be done because 
    the associated function argument is a function, or a set of overloaded 
    functions (13.4), and one or more of the following apply: 
    <UL class="dash">
      <LI>more than one function matches the function parameter type (resulting 
      in an ambiguous deduction), or</LI>
      <LI>no function matches the function parameter type, or</LI>
      <LI>the set of functions supplied as an argument contains one or more 
      function templates.</LI></UL></LI>
    <LI>A function parameter for which the associated argument is an initializer 
    list (8.5.4) but the parameter does not have a type for which deduction from 
    an initializer list is specified (14.8.2.1). [&nbsp;<I>Example:</I> 
<PRE class="example"><CODE>template&lt;class T&gt; void g(T);
g({1,2,3}); // <EM>error: no argument deduced for T</EM></CODE>
</PRE>—<I>end 
    example</I>&nbsp;]</LI>
    <LI>A function parameter pack that does not occur at the end of the 
    <VAR>parameter-declaration-list</VAR>.</LI></UL></BLOCKQUOTE>
<H2><A id="Acknowledgments">Acknowledgments</A></H2>
<P>Numerous people gave constructive feedback regarding the use of <CODE class="prettyprint">auto</CODE> 
in template parameter lists in an <A href="http://isocpp.org/">isocpp.org</A> 
discussion <A href="https://groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-proposals/cqaS7PcU5Qc">thread</A>.</P>
<P>Special thanks to Mike Spertus and Gabriel dos Reis for their invaluable 
analysis and assistance.</P></BODY></HTML>
