<HTML>
<HEAD>
   <style>
     <!--
       P.indented {margin-left: 4em}
       XMP.indented {margin-left: 4em}
     -->
   </style>
   <TITLE>
	Local and Unnamed Types as Template Arguments
   </TITLE>
</HEAD>

<BODY>

<TABLE ALIGN=RIGHT CELLSPACING=0 CELLPADDING=0 >
<TR>
<TD ALIGN=RIGHT>Document number:</TD>

<TD>&nbsp;08-0167/N2657</TD>
</TR>

<TR>
<TD ALIGN=RIGHT>Date:</TD>

<TD>&nbsp;2008-06-10</TD>
</TR>

<TR>
<TD ALIGN=RIGHT>Author:</TD>

<TD>&nbsp;John Spicer, Edison Design Group</TD>
</TR>

<TR>
<TD></TD>

<TD>&nbsp;<TT>jhs@edg.com</TT></TD>
</TR>
</TABLE>

<BR CLEAR=ALL>

<CENTER>
<H2>
Local and Unnamed Types as Template Arguments
</H2>
</center>

<h3>
Introduction
</h3>

<p>
In N2402, Anthony Williams proposes that local types, and unnamed types be
usable as template arguments.  At the February 2008 (Bellevue) meeting, the
Core working group supported the use of local types but was concerned
about unnamed types.  In addition, the WG did not support the mechanism used
to accomplish this change in N2402.

<p>
I discussed the unnamed type issue with Anthony Williams and others.
Use of unnamed types as template arguments was considered a useful facility
and does not seem to present any particular implementation issues.  In
particular, it is fairly common practice to use unnamed enumerations in
header files.  Consequently, unnamed types have been retained in this
proposal.

Note that a namespace scope unnamed
enumeration in one translation unit is distinct from one in another
translation unit.  So in the example below, <tt>x</tt> and <tt>y</tt>
are initalized by two different instances of <tt>f</tt>

<xmp class=indented>
file1.c:

template <class T> int f(T t);
enum {e1};
int x = f(e1);


file2.c:

template <class T> int f(T t);
enum {e1};
int y = f(e1);
</xmp>

<p>
N2402 makes local types and unnamed types usable as template arguments by
giving them linkage.  As mentioned above, the Core Working Group did not
favor this solution.
This document provides drafting to allow local and unnamed types to be used
as template arguments by revising the rules for template arguments to permit
such types.

<h3>
Working Paper Changes
</h3>

<p>
Change 3.5 [basic.link] paragraph 8 as follows:

<BLOCKQUOTE>
A type without linkage shall not be used as the type of a variable or
function with linkage, unless
<bl>
<li>
the variable or function has extern "C" linkage<del>.</del><ins>, or</ins>
<li>
<ins>
the type without linkage
was named using a dependent type (14.6.2.1).
</ins>
</bl>
</BLOCKQUOTE>

<p>
Delete the following sentence from 3.5 [basic.link] paragraph 8:

<BLOCKQUOTE>
This implies that names with no linkage cannot be used as template
arguments (14.3).
</BLOCKQUOTE>


<p>
Add the following example after paragraph 8:

<BLOCKQUOTE>
<xmp class=indented>
[ Example:
template <class T> struct A {
    // in A<X>, the following is allowed because the type with no linkage
    // X is named using template parameter T.
    friend void f(A, T){}
};

template <class T> void g(T t) {
    A<T> at;
    f(at, t);
}

int main() {
    class X {} x;
    g(x);
}

</xmp>
-- end example]
</BLOCKQUOTE>

<p>
In 14.3.1 [temp.arg.type] paragraph 2 remove the following text:


<BLOCKQUOTE>
A type without linkage (3.5) shall not be
used as a template argument for a template type parameter.
</BLOCKQUOTE>

<p>
Replace the example in paragraph 2 with the following:

<BLOCKQUOTE>
[ Example:
<xmp class=indented>
template <class T> class X { };
template <class T> void f(T t) { }
struct {} unnamed_obj;
void f()
{
    struct A { };
    enum { e1 };
    typedef struct {} B;
    B b;
    X<A>  x1; // OK
    X<A*> x2; // OK
    X<B>  x3; // OK
    f(e1); // OK
    f(unnamed_obj); // OK
    f(b); // OK
}
</xmp>
-- end example]

</BLOCKQUOTE>

<h3>End of document.</h3>

</body>
</html>



