Template Type Parameters
Our compare function has one template type parameter. In general, we can use
a type parameter as a type specifier in the same way that we use a built-in or
class type specifier. In particular, a type parameter can be used to name the return
type or a function parameter type, and for variable declarations or casts inside the
function body:
// ok: same type used for the return type and parameter
template <typename T> T foo(T* p)
{
T tmp = *p; // tmp will have the type to which p points
// . . .
return tmp;
}
Each type parameter must be preceded by the keyword class or typename:
// error: must precede U with either typename or class
template <typename T, U> T calc(const T&, const U&);
These keywords have the same meaning and can be used interchangeably inside a
template parameter list. A template parameter list can use both keywords:
// ok: no distinction between typename and class in a template parameter list
template <typename T, class U> calc (const T&, const U&);
It may seem more intuitive to use the keyword typename rather than class
to designate a template type parameter. After all, we can use built-in (nonclass)
types as a template type argument. Moreover, typename more clearly indicates
that the name that follows is a type name. However, typename was added to C++
after templates were already in widespread use; some programmers continue to
use class exclusively.