1. Template class parameter of non type
For function templates and class templates, template parameters are not limited to types or adapters, pointers (iterators), and common values can also be used as template parameters. In the type parameter based template, you define specific details to determine the code, which are not really determined until the code is called. But here, we are faced with the fact that these details are values, not types. When we want to use a value based template, we must explicitly specify these values to be able to instantiate the template.
For example:
template<class T,size_t MAXSIZE>
size_t is a number of unsigned types. Its purpose is to ensure the size of objects in the storage memory. This type is defined in the cstddef header file. This definition appears in STL source code analysis.
Of course, it can also be an ordinary integer, such as:
template<typename T,int SIZE = 10> //You can not only have non type parameters, but also set default values for them class Test { // All set to public type, purely for convenience public: Test(); Test(T); Test(const Test &); T T_array[SIZE]; }; int main() { Test<int,20> T1; Test<double> T2; }
As shown in the above code, there are two template parameters, one is the type of data stored in the sequence table, and the other is the non type class template parameter, which is used to specify the maximum number of data stored in the current sequence table.
2. Non type template function parameters
In addition to the template class can have non type template parameters, template functions can also have non type template parameters.
using namespace std; template <class T, int value = 20> T&& add(const T& x) { return x + value; } int main() { cout << add<int>(5) << endl; cout << add<int, 30>(5) << endl; return 0; }
3. Restrictions on non type template parameters
Non type template parameters are limited. Generally speaking, they can be constant integers (including enumeration values) or pointers to external linked objects. Floating point numbers and class objects are not allowed to be non type template parameters, but very well, floating-point pointers are OK:
using namespace std; template <class T, double value = 20.0> T&& add(const T& x) { return x + value; } int main() { cout << add<int>(5) << endl; cout << add<int, 30>(5) << endl; return 0; }
If you do this, you will get the following error:
Severity code indicates that the project file line is disabled Error C2672 "add": no matching overloaded function found Error C2783 "T & & add (const T &)": failed to derive template parameters for "value" Error C2993 "double": illegal type of non type template parameter "value" Error C2993 "double": illegal type of non type template parameter "value" Error C2672 "add": no matching overloaded function found
In addition, you cannot use global type pointers as template parameters:
For example:
using namespace std; enum {a = 10}; template <class T, int *value = &a> T&& add(const T& x) { return x + *value; } int main() { int *value_1 = 15; cout << add<int>(5) << endl; cout << add<int, value_1>(5) << endl; return 0; }
But you can use a global function pointer as a template parameter
For example:
// Define a foreach function template to perform some operation on each element of the array // The specific operation is specified by the function pointer parameter of the template template<typename T, void (*f)(T &v)> void foreach(T array[], unsigned size) { for (unsigned i = 0; i < size; ++i) f(array[i]); } // Three function templates are used to define operations on array elements template<typename T> void inc(T &v) {++v;} template<typename T> void dec(T &v) {--v;} template<typename T> void print(T &v) {std::cout << ' ' << v;} int main() { int array[] = {1, 2, 3, 4, 5, 6, 7, 8}; using namespace std; foreach<int, print<int> >(array, 8); cout << endl; foreach<int, inc<int> >(array, 8); foreach<int, print<int> >(array, 8); cout << endl; foreach<int, dec<int> >(array, 8); foreach<int, print<int> >(array, 8); cout << endl; return 0; }
In the above example, foreach is defined as a function template, and the second template parameter is a function pointer. Because template parameters must be given at compile time, this foreach function implements a "static callback.". It is also worth noting that the first template parameter T is used in the definition of the second template parameter void(f)(Tv). This is legal. In the template parameter list, the declared template parameter can be used immediately to define subsequent template parameters. In the first mock exam, void(f)(Tv) constrains the pointer template parameter f to accept pointer parameters that are the same as the previous template parameter type. Then the three function templates defined are all operations on data elements, which are 1, 1 and print for element values respectively. In the main function, the foreach function template is called, and the static binding adds 1, subtracts 1 and prints each element of the array.