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.
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.
Myfilebuf<double,200> x;
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.
Myfilebuf<double, (75>25)> x; // valid
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.