Generic programming and templates, generic programming templates
Generic programming is to write code in a way independent of any specific type, and templates are the basis of generic programming.
1) Define a function template)
A function template is a type-independent function that can generate a specific version of the function.
The template definition starts with the keyword template, followed by the template parameter table enclosed by Angle brackets.
The template parameters can be type parameter or nontype parameter ). In the following program, T is a type parameter. I will analyze the type parameters and the non-type parameters in another article.
// implement strcmp-like generic compare functiontemplate <typename T>int compare(const T &v1, const T &v2){ if (v1 < v2) return -1; if (v2 < v1) return 1; return 0;}
When using a function template, the compiler binds the real parameters of the template to the template parameters. The compiler will determine what type is used to replace each type parameter, and what value is used to replace each non-type parameter, and then generate and compile (called Instantiation) functions of this version.
In the following example, the compiler uses int instead of T to create the first version, and string instead of T to create the second version.
// compiler instantiates int compare(const int&, const int&)cout << compare(1, 0) << endl;// compiler instantiates int compare(const string&, const string&)string s1 = “hi”, s2 = “world”;cout << compare(s1, s2) << endl;
The function template can also be declared as inline.
// inline specifier follows template parameter listtemplate <typename T> inline T min(const T&, const T&);
(2) Define a class template)
In a defined class template, the template parameters are used as placeholders for types or values, and specific types or values are provided when classes are used.
template <typename Type> class Queue{public: Queue(); Type & front(); const Type & front() const; void push(const Type &); void pop(); bool empty() const;private: // …};
Different from calling a function template, when using a class template, you must specify a real parameter for the template parameter display.
Queue<int> qi; // Queue that holds intsQueue<string> qs; // Queue that holds strings
(3) Template type parameters
Type parameters are composed of class or typename followed by specifiers. In the function template parameter table, they have the same meaning. In fact, typename is more intuitive than class. It clearly indicates that the following name is a type name (including the built-in type), and class can easily be associated with class declaration or class definition.
In addition, the typename keyword must be used when the nested dependency type (nested depended name) is used.
You can define type members within a class. If you want to use such a type inside the function template, you must be prompted to tell the compiler that the name is a type, otherwise the compiler cannot know whether it is a type or a value. By default, the compiler assumes that such a name specifies (static) data members rather than types. Therefore, if the keyword typename is removed from the following program, a compilation error will occur.
template <typename Parm, typename U>Parm fcn(Parm *array, U value){ typename Parm::size_type * p;}
(4) Non-type template parameters
The template parameter can also be a non-type parameter. When used, the non-type parameter is replaced by a constant expression.
// initialize elements of an array to zerotemplate <typename T, size_t N>void array_init(T (&parm)[N]){ for (size_t i = 0; i != N; ++i) parm[i] = 0;}…int x[42];double y[10];array_init(x); // instantiates array_init(int (&)[42])array_init(y); // instantiates array_init(double (&)[10])
(5) Compile generic programs
The template code needs to make some assumptions about the type used. For example, the compare () above requires that type T reload the "<" operator. Therefore, the Operations completed in the function template limit the types that can be used to instantiate the function.
When writing template code, there should be as few requirements for the real parameter type as possible. For example, the compare () function only uses the <operator, rather than the> operator.