______________________________________________________________________
14 Templates [temp]
______________________________________________________________________
1 A class template defines the layout and operations for an unbounded
set of related types. [Example: a single class template List might
provide a common definition for list of int, list of float, and list
of pointers to Shapes. ] A function template defines an unbounded set
of related functions. [Example: a single function template sort()
might provide a common definition for sorting all the types defined by
the List class template. ]
2 A template defines a family of types or functions.
template-declaration:
template < template-parameter-list > declaration
template-parameter-list:
template-parameter
template-parameter-list , template-parameter
The declaration in a template-declaration shall declare or define a
function or a class, define a static data member of a template class,
or define a template member of a class. A template-declaration is a
declaration. A template-declaration is a definition (also) if its
declaration defines a function, a class, or a static data member of a
template class. There shall be exactly one definition for each tem
plate in a program. [Note: there can be many declarations. ] How
ever, if the multiple definitions are in different translation units,
the behavior is undefined (and no diagnostic is required).
+------- BEGIN BOX 1 -------+
This - and all other requirements for unique definitions of templates
in this clause - will have to be rephrased to take the ODR into
account when the ODR is completely defined.
+------- END BOX 1 -------+
3 The name of a template obeys the usual scope and access control rules.
A template-declaration can appear only as a global declaration, as a
member of a namespace, as a member of a class, or as a member of a
class template. A member template shall not be virtual. A destructor
shall not be a template. A local class shall not have a member tem
plate.
4 A template shall not have C linkage. If the linkage of a template is
something other than C or C++, the behavior is implementation-defined.
5 [Example: An array class template might be declared like this:
template<class T> class Array {
T* v;
int sz;
public:
explicit Array(int);
T& operator[](int);
T& elem(int i) { return v[i]; }
// ...
};
The prefix template <class T> specifies that a template is being
declared and that a type-name T will be used in the declaration. In
other words, Array is a parameterized type with T as its parameter. ]
6 [Note: a class template definition specifies how individual classes
can be constructed much as a class definition specifies how individual
objects can be constructed. ]
7 A member template can be defined within its class or separately. A
member template of a template class that is defined outside its class
is specified with the template parameter list of the class followed by
the template parameter list of the member template. [Example:
template<class T> class string {
public:
template<class T2> int compare(const T2&);
template<class T2> string(const string<T2>& s) { /* ... */ }
// ...
};
template<class T> template<class T2> int string<T>::compare(const T2& s)
{
// ...
}
--end example]
14.1 Template names [temp.names]
1 A template can be referred to by a template-id:
template-id:
template-name < template-argument-list >
template-name:
identifier
template-argument-list:
template-argument
template-argument-list , template-argument
template-argument:
assignment-expression
type-id
template-name
2 A template-id that names a template class is a class-name (_class_).
3 A template-id that names a defined template class can be used exactly
like the names of other defined classes. [Example:
Array<int> v(10);
Array<int>* p = &v;
--end example] [Note: template-ids that name functions are discussed
in _temp.fct_. ]
4 A template-id that names a template class that has been declared but
not defined can be used exactly like the names of other declared but
undefined classes. [Example:
template<class T> class X; // X is a class template
X<int>* p; // ok: pointer to declared class X<int>
X<int> x; // error: object of undefined class X<int>
--end example]
5 The name of a template followed by a < is always taken as the begin
ning of a template-id and never as a name followed by the less-than
operator. Similarly, the first non-nested > is taken as the end of
the template-argument-list rather than a greater-than operator.
[Example:
template<int i> class X { /* ... */ }
X< 1>2 >x1; // syntax error
X<(1>2)>x2; // ok
template<class T> class Y { /* ... */ }
Y< X<1> > x3; // ok
--end example]
6 The name of a class template shall not be declared to refer to any
other template, class, function, object, enumeration, enumerator,
namespace, value, or type in the same scope. Unless explicitly speci
fied to have internal linkage, a template in namespace scope has
external linkage (_basic.link_). A global template name shall be
unique in a program.
7 In a template-argument, an ambiguity between a type-id and an expres
sion is resolved to a type-id. [Example:
template<class T> void f();
template<int I> void f();
void g()
{
f<int()>(); // ``int()'' is a type-id: call the first f()
}
--end example]
14.2 Name resolution [temp.res]
1 A name used in a template is assumed not to name a type unless it has
been explicitly declared to refer to a type in the context enclosing
the template declaration or is qualified by the keyword typename.
[Example:
// no B declared here
class X;
template<class T> class Y {
class Z; // forward declaration of member class
void f() {
X* a1; // declare pointer to X
T* a2; // declare pointer to T
Y* a3; // declare pointer to Y
Z* a4; // declare pointer to Z
typedef typename T::A TA;
TA* a5; // declare pointer to T's A
typename T::A* a6; // declare pointer to T's A
T::A* a7; // T::A is not a type name:
// multiply T::A by a7
B* a8; // B is not a type name:
// multiply B by a8
}
};
--end example]
2 In a template, any use of a qualified-name where the qualifier depends
on a template-parameter can be prefixed by the keyword typename to
indicate that the qualified-name denotes a type.
elaborated-type-specifier:
...
typename ::opt nested-name-specifier identifier full-template-argument-listopt
full-template-argument-list:
< template-argument-list >
3 If a specialization of that template is generated for a template-
argument such that the qualified-name does not denote a type, the spe
cialization is ill-formed. The keyword typename states that the fol
lowing qualified-name names a type. [Note: but gives no clue to what
that type might be. ] The qualified-name shall include a qualifier
containing a template parameter or a template class name.
4 Knowing which names are type names allows the syntax of every template
declaration to be checked. Syntax errors in a template declaration
can therefore be diagnosed at the point of the declaration exactly as
errors for non-template constructs. Other errors, such as type errors
involving template parameters, cannot be diagnosed until later; such
errors shall be diagnosed at the point of instantiation or at the
point where member functions are generated (_temp.inst_). Errors that
can be diagnosed at the point of a template declaration shall be diag
nosed there or later together with the dependent type errors. [Exam
ple:
template<class T> class X {
// ...
void f(T t, int i, char* p)
{
t = i; // typecheck at point of instantiation,
// or at function generation
p = i; // typecheck immediately at template declaration,
// at point of instantiation,
// or at function generation
}
};
--end example] No diagnostics shall be issued for a template defini
tion for which a valid specialization can be generated.
5 Three kinds of names can be used within a template definition:
--The name of the template itself, the names of the template-
parameters (_temp.param_), and names declared within the template
itself.
--Names from the scope of the template definition.
--Names dependent on a template-argument (_temp.arg_) from the scope
of a template instantiation.
6 [Example:
#include <iostream>
using namespace std;
template<class T> class Set {
T* p;
int cnt;
public:
Set();
Set<T>(const Set<T>&);
void printall()
{
for (int i = 0; i<cnt; i++)
cout << p[i] << '\n';
}
// ...
};
--end example] When looking for the declaration of a name used in a
template definition the usual lookup rules (_basic.lookup.unqual_) are
first applied. [Note: in the example, i is the local variable i
declared in printall, cnt is the member cnt declared in Set, and cout
is the standard output stream declared in iostream. However, not
every declaration can be found this way; the resolution of some names
must be postponed until the actual template-argument is known. For
example, even though the name operator<< is known within the defini
tion of printall() an a declaration of it can be found in <iostream>,
the actual declaration of operator<< needed to print p[i] cannot be
known until it is known what type T is (_temp.dep_). ]
7 If a name can be bound at the point of the template definition and it
is not a function called in a way that depends on a template-parameter
(as defined in _temp.dep_), it will be bound at the template defini
tion point and the binding is not affected by later declarations.
[Example:
void f(char);
template<class T> void g(T t)
{
f(1); // f(char)
f(T(1)); // dependent
f(t); // dependent
}
void f(int);
void h()
{
g(2); // will cause one call of f(char) followed
// by two calls of f(int)
g('a'); // will cause three calls of f(char)
}
--end example]
14.2.1 Locally declared names [temp.local]
1 Within the scope of a class template or a specialization of a template
the name of the template is equivalent to the name of the template
followed by the template-parameters enclosed in <>. [Example: the
constructor for Set can be referred to as Set() or Set<T>(). ] Other
specializations (_temp.spec_) of the class can be referred to by
explicitly qualifying the template name with appropriate template-
arguments. [Example:
template<class T> class X {
X* p; // meaning X<T>
X<T>* p2;
X<int>* p3;
};
template<class T> class Y;
template<> class Y<int> {
Y* p; // meaning Y<int>
};
--end example] [Note: see _temp.param_ for the scope of template-
parameters. ]
2 A template type-parameter can be used in an elaborated-type-specifier.
[Example:
template<class T> class A {
friend class T;
class T* p;
class T; // error: redeclaration of template parameter T
// (a name declaration, not an elaboration)
// ...
}
--end example]
3 However, a specialization of a template for which a type-parameter
used this way is not in agreement with the elaborated-type-specifier
(_dcl.type_) is ill-formed. [Example:
class C { /* ... */ };
struct S { /* ... */ };
union U { /* ... */ };
enum E { /* ... */ };
A<C> ac; // ok
A<S> as; // ok
A<U> au; // error: parameter T elaborated as a class,
// but the argument supplied for T is a union
A<int> ai; // error: parameter T elaborated as a class,
// but the argument supplied for T is an int
A<E> ae; // error: parameter T elaborated as a class,
// but the argument supplied for T is an enumeration
--end example]
14.2.2 Names from the template's enclosing scope [temp.encl]
1 If a name used in a template isn't defined in the template definition
itself, names declared in the scope enclosing the template are consid
ered. If the name used is found there, the name used refers to the
name in the enclosing context. [Example:
void g(double);
void h();
template<class T> class Z {
public:
void f() {
g(1); // calls g(double)
h++; // error: cannot increment function
}
};
void g(int); // not in scope at the point of the template
// definition, not considered for the call g(1)
--end example] [Note: a template definition behaves exactly like
other definitions. ] [Example:
void g(double);
void h();
class ZZ {
public:
void f() {
g(1); // calls g(double)
h++; // error: cannot increment function
}
};
void g(int); // not in scope at the point of class ZZ
// definition, not considered for the call g(1)
--end example]
14.2.3 Dependent names [temp.dep]
1 Some names used in a template are neither known at the point of the
template definition nor declared within the template definition. Such
names shall depend on a template-argument and shall be in scope at the
point of the template instantiation (_temp.inst_). [Example:
class Horse { /* ... */ };
ostream& operator<<(ostream&,const Horse&);
void hh(Set<Horse>& h)
{
h.printall();
}
In the call of Set<Horse>::printall(), the meaning of the << operator
used to print p[i] in the definition of Set<T>::printall()
(_temp.res_), is
operator<<(ostream&,const Horse&);
This function takes an argument of type Horse and is called from a
template with a template-parameter T for which the template-argument
is Horse. Because this function depends on a template-argument the
call is well-formed. ]
2 A function call depends on a template-argument if the call would have
a different resolution or no resolution if a type, template, or named
constant mentioned in the template-argument were missing from the pro
gram. [Example: some calls that depend on an argument type T are:
1)The function called has a parameter that depends on T according to
the type deduction rules (_temp.deduct_). For example: f(T),
f(Array<T>), and f(const T*).
2)The type of the actual argument depends on T. For example: f(T(1)),
f(t), f(g(t)), and f(&t) assuming that t has the type T.
3)A call is resolved by the use of a conversion to T without either an
argument or a parameter of the called function being of a type that
depended on T as specified in (1) and (2). For example:
struct B { };
struct T : B { };
struct X { operator T(); };
void f(B);
void g(X x)
{
f(x); // meaning f( B( x.operator T() ) )
// so the call f(x) depends on T
}
3 This ill-formed template instantiation uses a function that does not
depend on a template-argument:
template<class T> class Z {
public:
void f() {
g(1); // g() not found in Z's context.
// Look again at point of instantiation
}
};
void g(int);
void h(const Z<Horse>& x)
{
x.f(); // error: g(int) called by g(1) does not depend
// on template-parameter ``Horse''
}
The call x.f() gives raise to the specialization:
void Z<Horse>::f() { g(1); }
The call g(1) would call g(int), but since that call in no way depends
on the template-argument Horse and because g(int) wasn't in scope at
the point of the definition of the template, the call x.f() is ill-
formed.
4 On the other hand:
void h(const Z<int>& y)
{
y.f(); // fine: g(int) called by g(1) depends
// on template-parameter ``int''
}
Here, the call y.f() gives raise to the specialization:
void Z<int>::f() { g(1); }
The call g(1) calls g(int), and since that call depends on the tem
plate-argument int, the call y.f() is acceptable even though g(int)
wasn't in scope at the point of the template definition. ]
5 A name from a base class (of a non-dependent type) can hide the name
of a template-parameter. [Example:
struct A {
struct B { /* ... */ };
int a;
int Y;
};
template<class B, class a> struct X : A {
B b; // A's B
a b; // error: A's a isn't a type name
};
--end example]
6 However, a name from a template-argument cannot hide a name declared
within a template, a template-parameter, or a name from the template's
enclosing scopes. [Example:
int a;
template<class T> struct Y : T {
struct B { /* ... */ };
B b; // The B defined in Y
void f(int i) { a = i; } // the global a;
Y* p; // Y<T>
};
Y<A> ya;
The members A::B, A::a, and A::Y of the template argument A do not
affect the binding of names in Y<A>. ]
7 A name of a member can hide the name of a template-parameter. [Exam
ple:
template<class T> struct A {
struct B { /* ... */ };
void f();
};
template<class B> void A<B>::f()
{
B b; // A's B, not the template parameter
}
--end example]
14.2.4 Non-local names declared within a template [temp.inject]
1 Names that are not template members can be declared within a template
class or function. When a template is specialized, the names declared
in it are declared as if the specialization had been explicitly
declared at its point of instantiation. If a template is first spe
cialized as the result of use within a block or class, names declared
within the template shall be used only after the template use that
caused the specialization. [Example:
// Assume that Y is not yet declared
template<class T> class X {
friend class Y;
};
Y* py1; // ill-formed: Y is not in scope
void g()
{
X<C>* pc; // does not cause instantiation
Y* py2; // ill-formed: Y is not in scope
X<C> c; // causes instantiation of X<C>, so
// names from X<C> can be used
// here on
Y* py3; // ok
}
Y* py4; // ok
--end example]
14.3 Template instantiation [temp.inst]
1 A class generated from a class template is called a generated class.
A function generated from a function template is called a generated
function. A static data member generated from a static data member
template is called a generated static data member. A class definition
introduced by template<> is called an explicitly specialized class.
The name of the class in such a definition shall be a template-id. A
function definition introduced by template<> is called an explicitly
specialized function. The name of the function in such a definition
may be a template-id. A static data member definition introduced by
template<> is called an explicitly specialized static data member.
The name of the class in such a definition shall be a template-id.
+------- BEGIN BOX 2 -------+
Corfield: I don't think the above wording is quite right for either
nested class member templates or nested class members of class tem
plates.
+------- END BOX 2 -------+
A specialization is a class, function, or static data member that is
either generated or explicitly specialized. [Example:
template<class T = int> struct A
{
static int x;
};
template<class U> void g(U) { }
template<> struct A<double> { }; // specialize for T == double
template<> struct A<> { }; // specialize for T == int
template<> void g(char) { } // specialize for U == char
// U is deduced from the parameter type
template<> void g<int>(int) { } // specialize for U == int
template<> int A<char>::x = 0; // specialize for T == char
template<> int A<>::x = 1; // specialize for T == int
--end example]
2 [Note: the act of generating a class, function, or static data member
from a template is commonly referred to as template instantiation. ]
14.3.1 Template linkage [temp.linkage]
1 A function template has external linkage, as does a static member of a
class template. Every function template shall have the same defini
tion in every translation unit in which it appears.
+------- BEGIN BOX 3 -------+
Corfield: what about template<classT> static void f(T);? Should this
be ill-formed?
+------- END BOX 3 -------+
14.3.2 Point of instantiation [temp.point]
1 The point of instantiation of a template is the point where names
dependent on the template-argument are bound. That point is in the
nearest enclosing global or namespace scope containing the first use
of the template requiring its definition. All names declared in
global or namespace scope that are visible at that use are visible at
the point of instantiation. In particular the name of the class or
function that encloses that use is visible at the point of instantia
tion.
+------- BEGIN BOX 4 -------+
Corfield: the above wording resolves Spicer issue 7.4 as presented in
Monterey and accepted by the committee in general session by straw
vote. Unfortunately, WP wording for the resolution was accidentally
omitted from N0744 = 95-0144 so this resolution did not actually form
part of the formal motion. Gibbons, Corfield and Unruh felt that this
resolution should still be incorporated as they believe that the com
mittee voted on the formal motion on the understanding that the formal
motion accurately reflected what was presented in general session.
+------- END BOX 4 -------+
[Note: this implies that names used in a template definition cannot be
bound to local names or class member names from the scope of the tem
plate use. They can, however, be bound to names of namespace members.
For example:
template<class T> class Y {
public:
void f1() { g1(1); }
void f2() { g2(2); }
void f3() { g3(3); }
void f4() { g4(4); }
};
void k(const Y<int>& h)
{
void g1(int);
h.f1(); // error: g1(int) called by g1(1) not found
// local g1() not considered
}
class C {
void g2(int);
void m(const Y<int>& h)
{
h.f2(); // error: g2(int) called by g2(2) not found
// C::g2() not considered
}
};
namespace N {
void g3(int);
void n(const Y<int>& h)
{
h.f3(); // N::g3(int) called by g3(3)
}
}
void g4(int i)
{
Y<int> h;
h.f4(); // g4(int) called by g4(4)
}
--end note]
2 Names from both the namespace of the template itself and of the names
pace containing the point of instantiation of a specialization are
used to resolve names for the specialization. Overload resolution is
used to chose between functions with the same name in these two names
paces.
3 [Example:
namespace NN {
void g(int);
void h(int);
template<class T> void f(T t)
{
g(t);
h(t);
k(t);
}
}
namespace MM {
void g(double);
void k(double);
void m()
{
NN::f(1); // indirectly calls NN::g(int),
// NN::h, and MM::k.
NN::f(1.0); // indirectly calls MM::g(double),
// NN::h, and MM::k.
}
}
--end example]
4 If a name is found in both namespaces and overload resolution cannot
resolve a use, the program is ill-formed.
5 Each translation unit in which the definition of a template is used in
a way that require definition of a specialization has a point of
instantiation for the template. If this causes names used in the tem
plate definition to bind to different names in different translation
units, the one-definition rule has been violated and any use of the
template is ill-formed. Such violation does not require a diagnostic.
6 A template can be either explicitly instantiated for a given argument
list or be implicitly instantiated. A template that has been used in
a way that require a specialization of its definition will have the
specialization implicitly generated unless it has either been explic
itly instantiated (_temp.explicit_) or explicitly specialized
(_temp.spec_). An implementation shall not instantiate a function,
nonvirtual member function, class or member class that does not
require instantiation. It is unspecified whether or not an implemen
tation instantiates a virtual member function that does not require
instantiation.
+------- BEGIN BOX 5 -------+
Corfield: the previous wording was "However, virtual functions can be
instantiated for implementation purposes" - I believe the new wording
clarifies the intent.
+------- END BOX 5 -------+
7 [Example:
template<class T> class Z {
void f();
void g();
};
void h()
{
Z<int> a; // instantiation of class Z<int> required
Z<char>* p; // instantiation of class Z<char> not required
Z<double>* q; // instantiation of class Z<double> not required
a.f(); // instantiation of Z<int>::f() required
p->g(); // instantiation of class Z<char> required, and
// instantiation of Z<char>::g() required
}
Nothing in this example requires class Z<double>, Z<int>::g(), or
Z<char>::f() to be instantiated. --end example]
8 If a virtual function is instantiated, its point of instantiation is
immediately following the point of instantiation for its class.
9 The point of instantiation for a template used inside another template
and not instantiated previous to an instantiation of the enclosing
template is immediately before the point of instantiation of the
enclosing template. [Example:
namespace N {
template<class T> class List {
public:
T* get();
// ...
};
}
template<class K, class V> class Map {
List<V> lt;
V get(K);
// ...
};
void g(Map<char*,int>& m)
{
int i = m.get("Nicholas");
// ...
}
--end example] This allows instantiation of a used template to be
done before instantiation of its user.
10Implicitly generated template classes, functions, and static data mem
bers are placed in the namespace where the template was defined.
[Example: a call of lt.get() from Map<char*,int>::get() would place
List<int>::get() in the namespace N rather than in the global names
pace. ]
+------- BEGIN BOX 6 -------+
Name injection from an implicitly generated template function
specialization is under debate. That is, it might be banned or
restricted.
+------- END BOX 6 -------+
11If a template for which a definition is in scope is used in a way that
involves overload resolution, conversion to a base class, or pointer
to member conversion, the definition of a template specialization is
generated if the template is defined. [Example:
template<class T> class B { /* ... */ };
template<class T> class D : public B<T> { /* ... */ };
void f(void*);
void f(B<int>*);
void g(D<int>* p, D<char>* pp)
{
f(p); // instantiation of D<int> required: call f(B<int>*)
B<char>* q = pp; // instantiation of D<char> required:
// convert D<char>* to B<char>*
}
--end example]
12If an instantiation of a class template is required and the template
is declared but not defined, the program is ill-formed. [Example:
template<class T> class X;
X<char> ch; // error: definition of X required
--end example]
13Recursive instantiation is possible. [Example:
template<int i> int fac() { return i>1 ? i*fac<i-1>() : 1; }
int fac<0>() { return 1; }
int f()
{
return fac<17>();
}
--end example]
14There shall be an implementation quantity that specifies the limit on
the depth of recursive instantiations.
15The result of an infinite recursion in instantiation is undefined. In
particular, an implementation is allowed to report an infinite recur
sion as being ill-formed. [Example:
template<class T> class X {
X<T>* p; // ok
X<T*> a; // instantiation of X<T> requires
// the instantiation of X<T*> which requires
// the instantiation of X<T**> which ...
};
--end example]
16No program shall explicitly instantiate any template more than once,
both explicitly instantiate and explicitly specialize a template, or
specialize a template more than once for a given set of template-
arguments. An implementation is not required to diagnose a violation
of this rule.
17An explicit specialization or explicit instantiation of a template
shall be in the namespace in which the template was defined. [Exam
ple:
namespace N {
template<class T> class X { /* ... */ };
template<class T> class Y { /* ... */ };
template<class T> class Z {
void f(int i) { g(i); }
// ...
};
template<> class X<int> { /* ... */ }; // ok: specialization
// in same namespace
}
template class Y<int>; // error: explicit instantiation
// in different namespace
template class N::Y<char*>; // ok: explicit instantiation
// in same namespace
template<> class N::Y<double> { /* ... */ }; // ok: specialization
// in same namespace
--end example]
18A member function of an explicitly specialized class shall not be
implicitly generated from the general template. Instead, the member
function shall itself be explicitly specialized. [Example:
template<class T> struct A {
void f() { /* ... */ }
};
template<> struct A<int> {
void f();
};
void h()
{
A<int> a;
a.f(); // A<int>::f must be defined somewhere
}
template<> void A<int>::f() { /* ... */ }
--end example] Thus, an explicit specialization of a class implies
the declaration of specializations of all of its members. The defini
tion of each such specialized member which is used shall be provided
in some translation unit.
14.4 Explicit instantiation [temp.explicit]
1 A class or function specialization can be explicitly instantiated from
its template.
2 The syntax for explicit instantiation is:
explicit-instantiation:
template declaration
Where the unqualified-id in the declaration shall be a template-id.
[Example:
template class Array<char>;
template void sort<char>(Array<char>&);
--end example]
+------- BEGIN BOX 7 -------+
Corfield: requiring a template-id here seems unnecessary for cases
where the template arguments can be deduced from the function argu
ments. An explicit specialization does not require this \n should we
relax this requirement?
+------- END BOX 7 -------+
3 A declaration of the template shall be in scope at the point of
explicit instantiation.
4 A trailing template-argument can be left unspecified in an explicit
instantiation or explicit specialization of a template function pro
vided it can be deduced from the function argument type. [Example:
// instantiate sort(Array<int>&):
// deduce template-argument:
template void sort<>(Array<int>&);
--end example]
5 The explicit instantiation of a class implies the instantiation of all
of its members not previously explicitly specialized in the transla
tion unit containing the explicit instantiation.
14.5 Template specialization [temp.spec]
1 A specialized template function, a template class, or a static member
of a template can be declared by a declaration introduced by tem
plate<> except for a type member or template class member of a non-
specialized template class; that is:
specialization:
template < > declaration
A specialization of a static data member of a template is a definition
if the declaration includes an initializer; otherwise, it is a decla
ration.
+------- BEGIN BOX 8 -------+
Corfield: there is still no syntax for the definition of a static data
member of a template that requires default initialization.
template<> X Q<int>::x;
This is a declaration regardless of whether X can be default initial
ized.
+------- END BOX 8 -------+
[Example:
template<class T> class stream;
template<> class stream<char> { /* ... */ };
template<class T> void sort(Array<T>& v) { /* ... */ }
template<> void sort<char*>(Array<char*>&) ;
Given these declarations, stream<char> will be used as the definition
of streams of chars; other streams will be handled by template classes
generated from the class template. Similarly, sort<char*> will be
used as the sort function for arguments of type Array<char*>; other
Array types will be sorted by functions generated from the template.
]
2 A declaration of the template being specialized shall be in scope at
the point of declaration of a specialization. [Example:
template<> class X<int> { /* ... */ }; // error: X not a template
template<class T> class X { /* ... */ };
template<> class X<char*> { /* ... */ }; // fine: X is a template
--end example]
3 If a template is explicitly specialized then that specialization shall
be declared before the first use of that specialization in every
translation unit in which it is used. [Example:
template<class T> void sort(Array<T>& v) { /* ... */ }
void f(Array<String>& v)
{
sort(v); // use general template
// sort(Array<T>&), T is String
}
template<> void sort<String>(Array<String>& v); // error: specialize after use
template<> void sort<>(Array<char*>& v); // fine sort<char*> not yet used
--end example] If a function or class template has been explicitly
specialized for a template-argument list no specialization will be
implicitly generated for that template-argument list.
4 It is possible for a specialization with a given function signature to
be generated by more than one function template. In such cases,
explicit specification of the template arguments must be used to
uniquely identify the template function instance that is being spe
cialized. [Example:
template <class T> void f(T);
template <class T> void f(T*);
template <> void f(int*); // Ambiguous
template <> void f<int>(int*); // OK
template <> void f(int); // OK
--end example]
5 A function with the same name as a template and a type that exactly
matches that of a template is not a specialization (_temp.over.spec_).
6 A member template of a class template may be explicitly specialized
for a given instance of the class template. A specific instance of a
member template is specified using the template function specializa
tion syntax. Default arguments shall not be supplied in such declara
tions. [Example:
template<class T> struct A {
void f(T);
template<class X> void g(T,X);
};
// specialization
template<> void A<int>::f(int);
// out of class definition
template<class T> template<class X> void A<T>::g(T,X) { }
// specialization of member template
template<> template<class X> void A<int>::g(int,X);
// specialization of an instance of a member template
template<> template<>
void A<int>::g(int,char); // X deduced as char
template<> template<>
void A<int>::g<char>(int,char); // X specified as char
--end example]
14.6 Class template specializations [temp.class.spec]
1 A primary class template declaration is one in which the class tem
plate name is an identifier. A template declaration in which the
class template name is a template-id, is a partial specialization of
the class template named in the template-id. The primary template
shall be declared before any specializations of that template. A par
tial specialization shall be declared before any use of that template
that would use that partial specialization.
2 [Example:
template<class T1, class T2, int I> class A { }; // #1
template<class T, int I> class A<T, T*, I> { }; // #2
template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3
template<class T> class A<int, T*, 5> { }; // #4
template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5
3 The first declaration declares the primary (unspecialized) class tem
plate. The second and subsequent declarations declare specializations
of the primary template. ]
4 The template parameters are specified in the angle bracket enclosed
list that immediately follows the keyword template. A template also
has a template argument list. For specializations, this list is
explicitly written immediately following the class template name. For
primary templates, this list is implicitly described by the template
parameter list. Specifically, the order of the template parameters is
the sequence in which they appear in the template parameter list.
[Example: the template argument list for the primary template in the
example above is <T1, T2, I>. ]
5 A nontype argument is nonspecialized if it is the name of a nontype
parameter. All other nontype arguments are specialized.
6 Within the argument list of a class template specialization, the fol
lowing restrictions apply:
--A specialized nontype argument expression shall not involve a tem
plate parameter of the specialization.
--The type of a specialized nontype argument shall not depend on
another type parameter of the specialization.
--The argument list of the specialization shall not be identical to
the implicit argument list of the primary template.
14.6.1 Matching of class template [temp.class.spec.match]
specializations
1 When a template class is used in a context that requires a complete
instantiation of the class, it is necessary to determine whether the
instantiation is to be generated using the primary template or one of
the partial specializations. This is done by matching the template
arguments of the template class being used with the template argument
lists of the partial specializations.
--If no matches are found, the instantiation is generated from the
primary template.
--If exactly one matching specialization is found, the instantiation
is generated from that specialization.
--If more than one specialization is found, the partial order rules
(_temp.class.order_) are used to determine whether one of the spe
cializations is more specialized than the others. If none of the
specializations is more specialized than all of the other matching
specializations, then the use of the template class is ambiguous and
the program is ill-formed.
2 A specialization matches a given actual template argument list if the
template arguments of the specialization can be deduced from the
actual template argument list (_temp.deduct_). A nontype template
parameter can also be deduced from the value of an actual template
argument of a nontype parameter of the primary template. [Example:
3 A<int, int, 1> a1; // uses #1
A<int, int*, 1> a2; // uses #2, T is int, I is 1
A<int, char*, 5> a3; // uses #4, T is int
A<int, char*, 1> a4; // uses #5, T1 is int, T2 is char, I is 1
A<int*, int*, 2> a5; // ambiguous: matches #3 and #5
--end example]
4 In a class template reference, (e.g., A<int, int, 1>) the argument
list must match the template parameter list of the primary template.
The template arguments of a specialization are deduced from the argu
ments of the primary template. The template parameter list of a spe
cialization shall not contain default template argument values.1)
14.6.2 Partial ordering of class template [temp.class.order]
specializations
1 For two class template partial specializations, the first is at least
as specialized as the second if:
--the type arguments of the first template's argument list are at
_________________________
1) There is no way in which they could be used.
least as specialized as those of the second template's argument list
using the ordering rules for function templates (_temp.func.order_),
and
--each nontype argument of the first template's argument list is at
least as specialized as that of the second template's argument list.
2 A nontype argument is at least as specialized as another nontype argu
ment if:
--both are formal arguments,
--the first is a value and the second is a formal argument, or
--both are the same value.
3 A template class partial specialization is more specialized than
another if, and only if, it is at least as specialized as the other
template class partial specialization and that template class partial
specialization is not at least as specialized as the first. Otherwise
the two template class partial specializations are unordered.
14.6.3 Member functions of class [temp.class.spec.mfunc]
template specializations
1 The template parameter list of a member function of a class template
specialization shall match the template parameter list of the class
template specialization. The template argument list of a member func
tion of a class template specialization shall match the template argu
ment list of the class template specialization. A class template spe
cialization is a distinct template. The members of the class template
specialization are unrelated to the members of the primary template.
Class template specialization members that are used in a way that
requires a definition must be defined; the definitions of members of
the primary template will never be used to provide definitions for
members of a class template specialization. An explicit specializa
tion of a member of a class template specialization is declared in the
same way as an explicit specialization of the primary template.
[Example:
2
// primary template
template<class T, int I> struct A {
void f();
};
template<class T, int I> void A<T,I>::f() { }
// class template specialization
template<class T> struct A<T,2> {
void f();
void g();
void h();
};
// member of class template specialization
template<class T> void A<T,2>::g() { }
// explicit specialization
template<> void A<char,2>::h() { }
int main()
{
A<char,0> a0;
A<char,2> a2;
a0.f(); // ok
a2.g(); // ok
a2.h(); // ok
a2.f(); // no definition of f for A<T,2>
// the primary template is not used here
}
--end example]
14.7 Template parameters [temp.param]
1 The syntax for template-parameters is:
template-parameter:
type-parameter
parameter-declaration
type-parameter:
class identifieropt
class identifieropt = type-id
typename identifieropt
typename identifieropt = type-id
template < template-parameter-list > class identifieropt
template < template-parameter-list > class identifieropt = template-name
[Example:
template<class T> class myarray { /* ... */ };
template<class K, class V, template<class T> class C = myarray>
class Map {
C<K> key;
C<V> value;
// ...
};
--end example]
2 Default arguments shall not be specified in a declaration or a defini
tion of a specialization.
3 A type-parameter defines its identifier to be a type-name in the scope
of the template declaration. A type-parameter shall not be redeclared
within its scope (including nested scopes). A non-type template-
parameter shall not be assigned to or in any other way have its value
changed. [Example:
template<class T, int i> class Y {
int T; // error: template-parameter redefined
void f() {
char T; // error: template-parameter redefined
i++; // error: change of template-argument value
}
};
template<class X> class X; // error: template-parameter redefined
--end example]
4 A template-parameter that could be interpreted as either an parameter-
declaration or a type-parameter (because its identifier is the name of
an already existing class) is taken as a type-parameter. A template-
parameter hides a variable, type, constant, etc. of the same name in
the enclosing scope. [Example:
class T { /* ... */ };
int i;
template<class T, T i> void f(T t)
{
T t1 = i; // template-arguments T and i
::T t2 = ::i; // globals T and i
}
Here, the template f has a type-parameter called T, rather than an
unnamed non-type parameter of class T. ] There is no semantic differ
ence between class and typename in a template-parameter.
5 There are no restrictions on what can be a template-argument type
beyond the constraints imposed by the set of argument types
(_temp.arg_). In particular, reference types and types containing cv-
qualifiers are allowed. A non-reference template-argument cannot have
its address taken. When a non-reference template-argument is used as
an initializer for a reference a temporary is always used. [Example:
template<const X& x, int i> void f()
{
&x; // ok
&i; // error: address of non-reference template-argument
int& ri = i; // error: non-const reference bound to temporary
const int& cri = i; // ok: reference bound to temporary
}
--end example]
6 A non-type template-parameter shall not be of floating type. [Exam
ple:
template<double d> class X; // error
template<double* pd> class X; // ok
template<double& rd> class X; // ok
--end example]
7 A default template-argument is a type, value, or template specified
after = in a template-parameter. A default template-argument can be
specified in a template declaration or a template definition. The set
of default template-arguments available for use with a template in a
translation unit shall be provided by the first declaration of the
template in that unit.
8 If a template-parameter has a default argument, all subsequent tem
plate-parameters shall have a default argument supplied. [Example:
template<class T1 = int, class T2> class B; // error
--end example]
9 The scope of a template-argument extends from its point of declaration
until the end of its template. In particular, a template-parameter
can be used in the declaration of subsequent template-parameters and
their default arguments. [Example:
template<class T, T* p, class U = T> class X { /* ... */ };
template<class T> void f(T* p = new T);
--end example] A template-parameter cannot be used in preceding tem
plate-parameters or their default arguments.
10A template-parameter can be used in the specification of base classes.
[Example:
template<class T> class X : public Array<T> { /* ... */ };
template<class T> class Y : public T { /* ... */ };
--end example] [Note: the use of a template-parameter as a base class
implies that a class used as a template-argument must be defined and
not just declared. ]
14.8 Template arguments [temp.arg]
1 The types of the template-arguments specified in a template-id shall
match the types specified for the template in its template-parameter-
list. [Example: Arrays as defined in _temp_ can be used like this:
Array<int> v1(20);
typedef complex<double> dcomplex; // complex is a standard
// library template
Array<dcomplex> v2(30);
Array<dcomplex> v3(40);
v1[3] = 7;
v2[3] = v3.elem(4) = dcomplex(7,8);
--end example]
2 A non-type non-reference template-argument shall be a constant-
expression of non-floating type, the address of an object or a func
tion with external linkage, or a non-overloaded pointer to member.
The address of an object or function shall be expressed as &f, plain f
(for function only), or &X::f where f is the function or object name.
In the case of &X::f, X shall be a (possibly qualified) name of a
class and f the name of a static member of X. A pointer to member
shall be expressed as &X::m where X is a (possibly qualified) name of
a class and m is the name of a nonstatic member of X. In particular,
a string literal (_lex.string_) is not an acceptable template-argument
because a string literal is the address of an object with static link
age. [Example:
template<class T, char* p> class X {
// ...
X(const char* q) { /* ... */ }
};
X<int,"Studebaker"> x1; // error: string literal as template-argument
char p[] = "Vivisectionist";
X<int,p> x2; // ok
--end example]
3 Similarly, addresses of array elements and non-static class members
are not acceptable as template-arguments. [Example:
int a[10];
struct S { int m; static int s; } s;
X<&a[2],p> x3; // error: address of element
X<&s.m,p> x4; // error: address of member
X<&s.s,p> x5; // error: address of member (dot operator used)
X<&S::s,p> x6; // ok: address of static member
--end example]
4 Nor is a local type or a type with no linkage name an acceptable tem
plate-argument. [Example:
void f()
{
struct S { /* ... */ };
X<S,p> x3; // error: local type used as template-argument
}
--end example]
5 Similarly, a reference template-parameter shall not be bound to a tem
porary, an unnamed lvalue, or a named lvalue with no linkage. [Exam
ple:
template<const int& CRI> struct B { /* ... */ };
B<1> b2; // error: temporary required for template argument
int c = 1;
B<c> b1; // ok
--end example]
6 An argument to a template-parameter of pointer to function type shall
have exactly the type specified by the template parameter. This
allows selection from a set of overloaded functions. [Example:
void f(char);
void f(int);
template<void (*pf)(int)> struct A { /* ... */ };
A<&f> a; // selects f(int)
--end example]
7 If a template-argument to a template class is a function type and that
causes a declaration that does not use the syntactic form of a func
tion declarator to have function type, the program is ill-formed.
[Example:
template<class T> struct A {
static T t;
};
typedef int function();
A<function> a; // ill-formed: would declare A<function>::t
// as a static member function
--end example]
8 A template has no special access rights to its template-argument
types. A template-argument shall be accessible at the point where it
is used as a template-argument. [Example:
template<class T> class X { /* ... */ };
class Y {
private:
struct S { /* ... */ };
X<S> x; // ok: S is accessible
};
X<Y::S> y; // error: S not accessible
--end example]
9 When default template-arguments are used, a template-argument list can
be empty. In that case the empty <> brackets shall still be used.
[Example:
template<class T = char> class String;
String<>* p; // ok: String<char>
String* q; // syntax error
--end example] The notion of " array type decay" does not apply to
template-parameters. [Example:
template<int a[5]> struct S { /* ... */ };
int v[5];
int* p = v;
S<v> x; // fine
S<p> y; // error
--end example]
14.9 Type equivalence [temp.type]
1 Two template-ids refer to the same class or function if their template
names are identical and in the same scope and their template-arguments
have identical values. [Example:
template<class E, int size> class buffer;
buffer<char,2*512> x;
buffer<char,1024> y;
declares x and y to be of the same type, and
template<class T, void(*err_fct)()> class list { /* ... */ };
list<int,&error_handler1> x1;
list<int,&error_handler2> x2;
list<int,&error_handler2> x3;
list<char,&error_handler2> x4;
declares x2 and x3 to be of the same type. Their type differs from
the types of x1 and x4. ]
14.10 Function templates [temp.fct]
1 A function template specifies how individual functions can be con
structed. [Example: a family of sort functions, might be declared
like this:
template<class T> void sort(Array<T>&);
--end example] A function template specifies an unbounded set of
(overloaded) functions. A function generated from a function template
is called a template function, so is an explicit specialization of a
function template. Template arguments can either be explicitly speci
fied in a call or be deduced from the function arguments.
14.10.1 Explicit template argument [temp.arg.explicit]
specification
1 Template arguments can be specified in a call by qualifying the tem
plate function name by the list of template-arguments exactly as tem
plate-arguments are specified in uses of a class template. [Example:
void f(Array<dcomplex>& cv, Array<int>& ci)
{
sort<dcomplex>(cv); // sort(Array<dcomplex>)
sort<int>(ci); // sort(Array<int>)
}
and
template<class U, class V> U convert(V v);
void g(double d)
{
int i = convert<int,double>(d); // int convert(double)
char c = convert<char,double>(d); // char convert(double)
}
--end example]
2 Implicit conversions (_conv_) are accepted for a function argument for
which the parameter has been fixed by explicit specification of tem
plate-arguments. [Example:
template<class T> void f(T);
class Complex {
// ...
explicit Complex(double);
};
void g()
{
f<Complex>(1); // ok, means f<Complex>(Complex(1))
}
--end example]
3 For a template function name to be explicitly qualified by template
arguments, the name must be known to refer to a template. When the
name appears after . or -> in a postfix-expression, or after :: in a
qualified-id where the nested-name-specifier depends on a template
parameter, the member template name must be prefixed by the keyword
template. Otherwise the name is assumed to name a non-template.
4 [Example:
class X {
public:
template<size_t> X* alloc();
};
void f(X* p)
{
X* p1 = p->alloc<200>();
// ill-formed: < means less than
X* p2 = p->template alloc<200>();
// fine: < starts explicit qualification
}
--end example]
5 If a name prefixed by the keyword template in this way is not the name
of a member template function, the program is ill-formed.
14.10.2 Template argument deduction [temp.deduct]
1 Template arguments that can be deduced from the function arguments of
a call need not be explicitly specified. [Example:
void f(Array<dcomplex>& cv, Array<int>& ci)
{
sort(cv); // call sort(Array<dcomplex>)
sort(ci); // call sort(Array<int>)
}
and
void g(double d)
{
int i = convert<int>(d); // call convert<int,double>(double)
int c = convert<char>(d); // call convert<char,double>(double)
}
--end example]
2 Type deduction is done for each parameter of a function template that
contains a reference to a template parameter that is not explicitly
specified. The type of the parameter of the function template (call
it P) is compared to the type of the corresponding argument of the
call (call it A), and an attempt is made to find types for the tem
plate type arguments, and values for the template non-type arguments,
that will make P after substitution of the deduced values and explic
itly-specified values (call that the deduced P) compatible with the
call argument. Type deduction is done independently for each parame
ter/argument pair, and the deduced template argument types and values
are then combined. If type deduction cannot be done for any parame
ter/argument pair, of if for any parameter/argument pair the deduction
leads to more than one possible set of deduced values, or if different
parameter/argument pairs yield different deduced values for a given
template argument, or if any template argument remains neither deduced
nor explicitly specified, template argument deduction fails.
3 If P is not a reference type:
--if A is an array type, the pointer type produced by the array-to-
pointer standard conversion (_conv.array_) is used in place of A for
type deduction; otherwise,
--if A is a function type, the pointer type produced by the function-
to-pointer standard conversion (_conv.func_) is used in place of A
for type deduction; otherwise,
--the cv-unqualified version of A is used in place of A for type
deduction.
If P is a reference type, the type referred to by P is used in place
of P for type deduction.
4 In general, the deduction process attempts to find template argument
values that will make the deduced P identical to A. However, there
are three cases that allow a difference:
--If the original P is a reference type, the deduced P (i.e., the type
referred to by the reference) can be more cv-qualified than A.
--If P is a pointer or pointer to member type, A can be another
pointer or pointer to member type that can be converted to the
deduced P via a qualification conversion (_conv.qual_).
--If P is a class, A can be a derived class of the deduced P having
the form class-template-name<arguments>. Likewise, if P is a
pointer to a class, A can be a pointer to a derived class of the
underlying type of the deduced P having the form class-template-
name<arguments>. These alternatives are considered only if type
deduction cannot be done otherwise. If they yield more than one
possible deduced P, the type deduction fails.
When deducing arguments in the context of taking the address of an
overloaded function (_over.over_), these inexact deductions are not
considered.
5 A template type argument T or a template non-type argument i can be
deduced if P and A have one of the following forms:
T
cv-list T
T*
T&
T[integer-constant]
class-template-name<T>
type(*)(T)
type T::*
T(*)()
T(*)(T)
type[i]
class-template-name<i>
6 where (T) represents parameter lists where at least one parameter type
contains a T, and () represents parameter lists where no parameter
contains a T. Similarly, <T> represents template argument lists where
at least one argument contains a T, and <i> represents template argu
ment lists where at least one argument contains an i. These forms can
be used in the same way as T is for further composition of types.
[Example:
X<int> (*)(char[6])
is of the form
class-template-name<T> (*)(type[i])
which is a variant of
type (*)(T)
where type is X<int> and T is char[6]. ]
7 [Note: the template type parameter cannot be deduced from the type of
a nontype template argument. ]
8 In addition, a template-parameter can be deduced from a function or
pointer to member function argument if the set of overloaded functions
does not contain template functions and at most one of a set of over
loaded functions provides a unique match. [Example:
template<class T> void f(void(*)(T,int));
template<class T> void foo(int, T);
void g(int,int);
void g(char,int);
void h(int,int,int);
void h(char,int);
int m()
{
f(&g); // error: ambiguous
f(&h); // ok: void h(char,int) is a unique match
f(&foo); // error: type deduction fails because foo is a template
}
--end example]
9 Template arguments cannot be deduced from function arguments involving
constructs other than the ones specified in here (_temp.deduct_).
+------- BEGIN BOX 9 -------+
Can a template template-parameter be deduced? and if so how? Cor
field: This was Spicer issue 3.19 which disappeared after the Waterloo
meeting when template template-parameters were accepted. This does not
appear to be on the current template issues list.
+------- END BOX 9 -------+
10Template arguments of an explicit instantiation or explicit special
ization are deduced (_temp.explicit_, _temp.spec_) according to these
rules specified for deducing function arguments.
11[Note: a major array bound is not part of a function parameter type,
except for reference types, so it can't be deduced from an argument:
template<int i> void f1(int a[10][i]);
template<int i> void f2(int a[i][20]);
template<int i> void f3(int (&a)[i][20]);
void g()
{
int v[10][20];
f1(v); // ok: i deduced to be 20
f1<10>(v); // ok
f2(v); // error: cannot deduce template-argument i
f2<10>(v); // ok
f3(v); // ok: i deduced to be 10
}
--end note]
12If a nontype parameters is used in an expression in the function dec
laration, template argument deduction fails. The type of the function
template-parameter shall match the type of the template-argument
exactly, except that a template parameter deduced from an array bound
may be any integral type.2) [Example:
template<int i> class A { /* ... */ };
template<short s> void f(A<s>);
template<short s> void g(A<s+1>);
A<1> a;
f(a); // error: deduction fails for conversion from short to int
g(a); // error: deduction fails for expression s+1
f<1>(a); // ok
g<0>(a); // ok
--end example]
13If function template-arguments are explicitly specified in a call they
are specified in declaration order. Trailing arguments can be left
out of a list of explicit template-arguments. [Example:
template<class X, class Y, class Z> X f(Y,Z);
void g()
{
f<int,char*,double>("aa",3.0);
f<int,char*>("aa",3.0); // Z is deduced to be double
f<int>("aa",3.0); // Y is deduced to be char*, and
// Z is deduced to be double
f("aa",3.0); // error: X cannot be deduced
}
--end example]
14A template-parameter cannot be deduced from a default function argu
ment. [Example:
template <class T> void f(T = 5, T = 7);
void g()
{
f(1); // ok: call f<int>(1,7)
f(); // error: cannot deduce T
f<int>(); // ok: call f<int>(5,7)
}
15Here is example in which different parameter/argument pairs produce
inconsistent template argument deductions:
_________________________
2) Although a template-parameter of type bool may be deduced from an
array bound, the resulting value will always be true because the array
bound will be non-zero.
template<class T> void f(T x, T y) { /* ... */ }
struct A { /* ... */ };
struct B : A { /* ... */ };
int g(A a, B b)
{
f(a,a); // ok: T is A
f(b,b); // ok: T is B
f(a,b); // error T could be A or B
f(b,a); // error: T could be A or B
}
16Here is an example where a qualification conversion applies between
the call argument type and the deduced parameter type:
template<class T> void f(const T*) {}
int *p;
void s()
{
f(p); // f(const int *)
}
17Here is an example where the deduced parameter type is a derived class
of a class template reference:
template <class T> struct B { };
template <class T> struct D : public B<T> {};
struct D2 : public B<int> {};
template <class T> void f(B<T>&){}
void main()
{
D<int> d;
D2 d2;
f(d); // calls f(B<int>&)
f(d2); // calls f(B<int>&)
}
--end example]
14.10.3 Overload resolution [temp.over]
1 A function template can be overloaded either by (other) functions of
its name or by (other) function templates of that same name. When a
call to that name is written (explicitly, or implicitly using the
operator notation), template argument deduction (_temp.deduct_) is
performed on each function template to find the template argument val
ues (if any) that can be used with that function template to generate
a function that can be invoked with the call arguments. For each
function template, if the argument deduction succeeds, the deduced
template arguments are used to generate a single template function,
which is added to the candidate functions set to be used in overload
resolution. If, for a given function template, argument deduction
fails, no such function is added to the set of candidate functions for
that template. The complete set of candidate functions includes all
the template functions generated in this way and all of the non-
template overloaded functions of the same name. The template func
tions are treated like any other functions in the remainder of over
load resolution, except as explicitly noted.3)
2 [Example:
template<class T> T max(T a, T b) { return a>b?a:b; };
void f(int a, int b, char c, char d)
{
int m1 = max(a,b); // max(int a, int b)
char m2 = max(c,d); // max(char a, char b)
int m3 = max(a,c); // error: cannot generate max(int,char)
}
3 Adding
int max(int,int);
to the example above would resolve the third call, by providing a
function that could be called for max(a,c) after using the standard
conversion of char to int for c.
4 Here is an example involving conversions on a function argument
involved in template-parameter deduction:
template<class T> struct B { /* ... */ };
template<class T> struct D : public B<T> { /* ... */ };
template<class T> void f(B<T>&);
void g(B<int>& bi, D<int>& di)
{
f(bi); // f(bi)
f(di); // f( (B<int>&)di )
}
5 Here is an example involving conversions on a function argument not
involved in template-parameter deduction:
_________________________
3) The parameters of template functions contain no template parameter
types. The set of conversions allowed on deduced arguments is limit
ed, because the argument deduction process produces template functions
with parameters that either match the call arguments exactly or differ
only in ways that can be bridged by the allowed limited conversions.
Non-deduced arguments allow the full range of conversions.
template<class T> void f(T*,int); // #1
template<class T> void f(T,char); // #2
void h(int* pi, int i, char c)
{
f(pi,i); // #1: f<int>(pi,i)
f(pi,c); // #2: f<int*>(pi,c)
f(i,c); // #2: f<int>(i,c);
f(i,i); // #2: f<int>(i,char(i))
}
--end example]
6 The template definition is needed to generate specializations of a
template. However, only a function template declaration is needed to
call a specialization. [Example:
template<class T> void f(T); // declaration
void g()
{
f("Annemarie"); // call of f<char*>
}
The call of f is well formed because of the declaration of f, and the
program will be ill-formed unless a definition of f is present in some
translations unit.
7 Here is a case involving explicit specification of some of the tem
plate arguments and deduction of the rest:
template<class X, class Y> void f(X,Y*); // #1
template<class X, class Y> void f(X*,Y); // #2
void g(char* pc, int* pi)
{
f(0,0); // error: ambiguous: f<int,int>(int,int*)
// or f<int,int>(int*,int) ?
f<char*>(pc,pi); // #1: f<char*,int>(char*,int*)
f<char>(pc,pi); // #2: f<char,int*>(char*,int*)
}
--end example]
14.10.4 Overloading and linkage [temp.over.link]
1 It is possible to overload template functions so that specializations
of two different template functions have the same type. [Example:
// file1.c // file2.c
template<class T> template<class T>
void f(T*); void f(T);
void g(int* p) { void h(int* p) {
f(p); // call f_PT_pi f(p); // call f_T_pi
} }
--end example]
2 Such specializations are distinct functions and do not violate the
ODR.
3 The signature of a specialization of a template function consists of
the actual template arguments (whether explicitly specified or
deduced) and the signature of the function template.
4 The signature of a function template consists of its function signa
ture and its return type and template parameter list. The names of
the template parameters are significant only for establishing the
relationship between the template parameters and the rest of the sig
nature.
14.10.5 Overloading and specialization [temp.over.spec]
1 A template function can be overloaded by a function with the same type
as a potentially generated function. [Example:
template<class T> T max(T a, T b) { return a>b?a:b; }
int max(int a, int b);
int min(int a, int b);
template<class T> T min(T a, T b) { return a<b?a:b; }
--end example] Such an overloaded function is a specialization but
not an explicit specialization. The declaration simply guides the
overload resolution. [Note: this implies that a definition of
max(int,int) and min(int,int) will be implicitly generated from the
templates. If such implicit instantiation is not wanted, the explicit
specialization syntax should be used instead:
template<class T> T max(T a, T b) { return a>b?a:b; }
template<> int max<int>(int a, int b);
--end note]
2 Defining a function with the same type as a template specialization
that is called is ill-formed. [Example:
template<class T> T max(T a, T b) { return a>b?a:b; }
int max(int a, int b) { return a>b?a:b; }
void f(int x, int y)
{
max(x,y); // error: duplicate definition of max()
}
If the two definitions of max() are not in the same translation unit
the diagnostic is not required. If a separate definition of a func
tion max(int,int) is needed, the specialization syntax can be used.
If the conversions enabled by an ordinary declaration are also needed,
both can be used.
template<class T> T max(T a, T b) { return a>b?a:b; }
template<> int max<>(int a, int b) { /* ... */ }
void g(char x, int y)
{
max(x,y); // error: no exact match, and no conversions allowed
}
int max(int,int);
void f(char x, int y)
{
max(x,y); // max<int>(int(x),y)
}
--end example]
3 An explicit specialization of a function template shall be inline or
static only if it is explicitly declared to be, and independently of
whether its function template is. [Example:
template<class T> void f(T) { /* ... */ }
template<class T> inline T g(T) { /* ... */ }
template<> inline void f<>(int) { /* ... */ } // ok: inline
template<> int g<>(int) { /* ... */ } // ok: not inline
--end example]
14.10.6 Partial ordering of function templates [temp.func.order]
1 Given two function templates, whether one is more specialized than
another can be determined by transforming each template in turn and
using argument deduction to compare it to the other.
2 The transformation used is:
--For each type template parameter, synthesize a unique type and sub
stitute that for each occurrence of that parameter in the function
parameter list.
--for each nontype template parameter, synthesize a unique value of
the appropriate type and substitute that for each occurrence of that
parameter in the function parameter list.
3 Using the transformed function parameter list, perform argument deduc
tion against the other function template (_temp.deduct_). The trans
formed template is at least as specialized as the other if, and only
if, the deduction succeeds and the deduced parameter types are an
exact match (so the deduction does not rely on implicit conversions).
4 A template is more specialized than another if, and only if, it is at
least as specialized as the other template and that template is not at
least as specialized as the first. [Example:
template<class T> class A {};
template<class T> void f(T);
template<class T> void f(T*);
template<class T> void f(const T*);
template<class T> void g(T);
template<class T> void g(T&);
template<class T> void h(const T&);
template<class T> void h(A<T>);
void m() {
const int *p;
f(p); // f(const T*) is more specialized than f(T) or f(T*)
float x;
g(x); // Ambiguous: g(T) or g(T&)
A<int> z;
h(z); // h(A<T>) is more specialized than f(const T&)
const A<int> z2;
h(z2); // h(const T&) is called because h(A<T>) is not callable
}
--end example]
14.11 Member function templates [temp.mem.func]
1 A member function of a template class is implicitly a template func
tion with the template-parameters of its class as its template-
parameters. [Example:
template<class T> class Array {
T* v;
int sz;
public:
explicit Array(int);
T& operator[](int);
T& elem(int i) { return v[i]; }
// ...
};
declares three function templates. The subscript function might be
defined like this:
template<class T> T& Array<T>::operator[](int i)
{
if (i<0 || sz<=i) error("Array: range error");
return v[i];
}
2 The template-argument for Array<T>::operator[]() will be determined by
the Array to which the subscripting operation is applied.
Array<int> v1(20);
Array<dcomplex> v2(30);
v1[3] = 7; // Array<int>::operator[]()
v2[3] = dcomplex(7,8); // Array<dcomplex>::operator[]()
--end example]
14.12 Member class templates [temp.mem.class]
1 A member class of a template class is implicitly a template class with
the template-parameters of its class as its template-parameters.
2 A member class of a template class defined after the template class
which declares it shall be defined before the first use which requires
instantiation. [Example:
template<class T> struct A {
class B;
};
A<int>::B* b1; // ok: requires A to be defined but not A::B
template<class T> class A<T>::B { };
A<int>::B b2; // ok: requires A::B to be defined
--end example]
+------- BEGIN BOX 10 -------+
Unruh: this subclause was added to state that the semantics of tem
plate classes apply to member class templates. The rest of clause 14
[temp] needs a careful review to ensure that this has no further
implications. This relates to Spicer issue 2.25 resolved in Monterey.
+------- END BOX 10 -------+
14.13 Friends [temp.friend]
1 A friend function of a template can be a template function or a non-
template function. [Example:
template<class T> class task {
// ...
friend void next_time();
friend task<T>* preempt(task<T>*);
friend task* prmt(task*); // task is task<T>
friend class task<int>;
// ...
};
Here, next_time() and task<int> become friends of all task classes,
and each task has appropriately typed functions preempt() and prmt()
as friends. The preempt functions might be defined as a template.
template<class T> task<T>* preempt(task<T>* t) { /* ... */ }
--end example]
2 A friend template may be defined within a class. [Example:
class A {
template<class T> friend class B { /* ... /* }; // ok
template<class T> friend void f(T){ /* ... /* } // ok
};
Note: a friend declaration can add a name to an enclosing scope
(_temp.inject_). --end example]
3 A member of a class template may be declared to be a friend. [Exam
ple:
template<class T> struct A {
struct B { };
void f();
};
class C {
template<class T> friend struct A<T>::B;
template<class T> friend void A<T>::f();
};
--end example]
14.14 Static members and variables [temp.static]
1 Each template class or function generated from a template has its own
copies of any static variables or members. [Example:
template<class T> class X {
static T s;
// ...
};
X<int> aa;
X<char*> bb;
Here X<int> has a static member s of type int and X<char*> has a
static member s of type char*. ]
2 Static class member templates are defined similarly to member function
templates. [Example:
template<class T> T X<T>::s = 0;
template<> int X<int>::s = 3;
3 Similarly,
template<class T> f(T* p)
{
static T s;
// ...
};
void g(int a, char* b)
{
f(&a); // call f<int>(int*)
f(&b); // call f<char*>(char**)
}
Here f<int>(int*) has a static member s of type int and
f<char*>(char**) has a static member s of type char*. ]