|
กก |
Function templatesTemplates allow to create generic functions that admit any data type as parameters or return value without necessity to overload a function with all the possible data types. Until certain point they fulfill the functionality of a macro. Its prototype is anyone of the two following ones:template <class indetifier> function_declaration;the only difference between both prototypes is the use of keyword class or typename, its use is indistinct since both expressions have exactly the same behavior. For example, to create a template function that returns the greater one of two objects we could use:
As specifies the first line, we have created a template for a generic data type that we
have called GenericType. Therefore in the function that follows,
GenericType is a valid data type and is used as return value
for the function GetMax and as type for its two parameters
a and b.
GenericType does not still represent any concrete data type;
when the function GetMax will be called we will be able
to call it with any valid data type. This data type will serve as pattern and
will replace GenericType in the function.
The way to call a template class with a type pattern is the following one:
function <pattern> (parameters);Thus, for example, to call GetMax and to compare two integer values of type int we can write: int x,y;so GetMax will be called as if each appearance of GenericType was replaced by an int expression. Ok, here is the complete example:
(In this case we have called the generic type T instead of GenericType because it is shorter and in addition is one of the most usual identifiers used for templates, although it is possible to use any valid identifier). In the example above we used the same function GetMax() with arguments of type int and long having written a single implementation of the function. That is to say, we have written a function template and called it with two different patterns. As you can see, within our GetMax() template function the type T can be used to declare new objects: T result;result is an object of type T, like a and b, that is to say, of the type that we enclose between angle-brackets <> when calling our template function. In this concrete case where the generic T type is used as parameter for function GetMax the compiler can find out automatically which data type is passed to it without having you to specify it with patterns <int> or <long>. That is, we could have written: int i,j;since being both i and j of type int the compiler would assume automatically that the wished function is with type int. This implicit method is more usual and would produce the same result:
Notice how in this case, within function main() we called our template function GetMax() without explicitly specifying the type between angle-brackets <>. The compiler automatically determines what type is needed on each call. Because our template function includes only one data type (class T) and both arguments that it admits are both of that same type, we cannot call to our template function with two objects of different types as parameters: int i;It would be incorrect, since our function waits for two arguments of the same type (or class). We can also make template-functions that admit more than a single generic class or data type. For example:
In this case, our template function GetMin() admits two parameters of
different types and returns an object of the same type that the first parameter
(T) that is passed. For example, after that declaration we could call
the function in the following way:
or evenint i,j; long l; i = GetMin<int,long> (j,l); although j and l are of different types.i = GetMin (j,l);
Class templatesWe also have the possibility to write class templates, so that a class can have members based on generic types that do not need to be defined at the moment of creating the class or whose members use these generic types. For example:
The class that we have just defined serves to store two elements of any valid type.
For example, if we wanted to declare an object of this class to store two integer values
of type int with the values
115 and 36 we would write:
pair<int> myobject (115, 36);this same class would serve also to create an object to store any other type: pair<float> myfloats (3.0, 2.18);The only member function has been defined inline within the class declaration, nevertheless if this is not thus and we define a function member outside the declaration we always must also precede the definition with prefix template <... >.
template <class T>All Ts that appear are necessary, reason why whenever you declare member functions you will have to follow a format similar to this (the second T makes reference to the type returned by the function, so this may vary).
Template specializationA template specialization allows to make specific implementations in a template for when the pattern is a concrete type. For example, suppose that our class template pair included a function to return the result of the module operation between the objects contained in it, but we only want that it works when the contained type is int and for the rest of types we want that this function always return 0. This can be made this way:
As you can see in the code the specialization is defined this way: template <> class class_name <type>The specialization is part of a template, for that reason we must begin the declaration with template <>. And indeed because it is a specialization for a concrete type the generic type cannot be used in it, as well as the first angle-brackets <> must appear empty. After the class name we must include the type that is being specialized enclosed between angle-brackets <>. When we specialize a type of a template we must also define all the members adequating them to the specialization (if one pays attention, in the example above we have had to include its own constructor, although it is identic to the one in the generic template). The reason is that no member is inherited from the generic template to the specialization.
Parameter values for templatesBesides the arguments preceded by class keyword that represent a type, functions templates and class templates can include other parameters that are not types whenever they be also constant values, like for example values of fundamental types. As example see this class template that serves to store arrays:
It is also possible to set default values to any template parameter just as done in function parameters. Possible template examples: template <class T> // The most usual: one class parameter. template <class T, class U> // Two class parameters. template <class T, int N> // A class and an integer. template <class T = char> // With a default value. template <int Tfunc (int)> // A function as parameter.
| ||||||||||||||||||||