Template non-type arguments (C++ only)
A non-type template argument provided within a template argument list is an expression whose value can be determined at compile time. Such arguments must be constant expressions, addresses of functions or objects with external linkage, or addresses of static class members. Non-type template arguments are normally used to initialize a class or to specify the sizes of class members.
For non-type integral arguments, the instance argument matches the corresponding template parameter as long as the instance argument has a value and sign appropriate to the parameter type.
For non-type address arguments, the type of the instance argument must be of the form identifier or &identifier, and the type of the instance argument must match the template parameter exactly, except that a function name is changed to a pointer to function type before matching.
The resulting values of non-type template arguments within a template argument list form part of the template class type. If two template class names have the same template name and if their arguments have identical values, they are the same class.
int
argument as
well as the type argument: template<class T, int size> class Myfilebuf
{
T* filepos;
static int array[size];
public:
Myfilebuf() { /* ... */ }
~Myfilebuf();
advance(); // function defined elsewhere in program
};
In this example, the template argument size
becomes
a part of the template class name. An object of such a template class
is created with both the type argument T
of the class
and the value of the non-type template argument size
.
x
, and its corresponding template
class with arguments double
and size=200
,
can be created from this template with a value as its second template
argument: Myfilebuf<double,200> x;
x
can also be created using an arithmetic
expression: Myfilebuf<double,10*20> x;
The objects created by these expressions are identical
because the template arguments evaluate identically. The value 200
in
the first expression could have been represented by an expression
whose result at compile time is known to be equal to 200
,
as shown in the second construction.
<
symbol
or the >
symbol must be enclosed in parentheses
to prevent either symbol from being parsed as a template argument
list delimiter when it is in fact being used as a relational operator. For
example, the arguments in the following definition are valid: Myfilebuf<double, (75>25)> x; // valid
>
) is interpreted as the closing delimiter
of the template argument list: Myfilebuf<double, 75>25> x; // error
Myfilebuf<double,200> x; // create object x of class
// Myfilebuf<double,200>
Myfilebuf<double,200.0> y; // error, 200.0 is a double,
// not an int
The instantiation of y
fails because
the value 200.0
is of type double
,
and the template argument is of type int
.
Myfilebuf<double, 128> x
Myfilebuf<double, 512> y
are objects of separate template specializations. Referring
either of these objects later with Myfilebuf<double>
is
an error.
template<int i> class C
{
public:
int k;
C() { k = i; }
};
class C<100>;
class C<200>;
Again, these two declarations refer to distinct classes because the values of their non-type arguments differ.