As with a function parameter, the name chosen by the programmer for a template parameter has no intrinsic meaning. In our example, we named compare's template type parameter T, but we could have named it anything:
template <class Glorp>
int compare(const Glorp &v1, const Glorp &v2)
{
if (v1 < v2) return -1;
if (v2 < v1) return 1;
return 0;
}
This code defines the same comparetemplate as before.
Template Parameter Scope
The name of a template parameter can be used after it has been declared as a template
parameter and until the end of the template declaration or definition.
Template parameters follow normal name-hiding rules. A template parameter with the same
name as an object, function, or type declared in global scope hides the global name:
typedef double T;
template <class T> T calc(const T &a, const T &b)
{
// tmp has the type of the template parameter T
// not that of the global typedef
T tmp = a;
// ...
return tmp;
}
Restrictions on the Use of a Template Parameter Name
A name used as a template parameter may not be reused within the template:
template <class T> T calc(const T &a, const T &b)
{
typedef double T; // error: redeclares template parameter T
T tmp = a;
// ...
return tmp;
}
This restriction also means that the name of a template parameter can be used only once within
the same template parameter list:
// error: illegal reuse of template parameter name V
template <class V, class V> V calc(const V&, const V&) ;
Of course, just as we can reuse function parameter names, the name of a template parameter
can be reused across different templates:
// ok: reuses parameter type name across different templates
template <class T> T calc (const T&, const T&) ;
template <class T> int compare(const T&, const T&) ;
Template Declarations
As with any other function or class, we can declare a template without defining it. A declaration
must indicate that the function or class is a template:
// declares compare but does not define it
template <class T> int compare(const T&, const T&) ;
The names of the template parameters need not be the same across declarations and the
definition of the same template:
// all three uses of calc refer to the same function template
// forward declarations of the template
template <class T> T calc(const T&, const T&) ;
template <class U> U calc(const U&, const U&) ;
// actual definition of the template
template <class Type>
Type calc(const Type& a, const Type& b) { /* ... */ }
Each template type parameter must be preceded either by the keyword classor typename;
each nontype parameter must be preceded by a type name. It is an error to omit the keyword
or a type specifier:
// error: must precede U by either typename or class
template <typename T, U> T calc (const T&, const U&) ;