䊐 Multiple Template ParametersYou can also define templates with multiple parameters like the following class template, Example: template class Demo { //.. The following expression woul
Trang 1䊐 Multiple Template Parameters
You can also define templates with multiple parameters like the following class template,
Example: template <class U, class V>
class Demo
{ // };
which has two parameters UandV A class Demo<U,V>is defined for each pair of U,V
types
A template parameter need not always be a type name Normal function parameters are also permissible, particularly pointers and references
Example: template<class T, int n>
class Stack{ };
This defines the class template Stack<T, n>that is parameterized with the type Tand
an integer n
The example on the opposite page uses the parameter nto specify the size of an array used to represent a stack The major advantage is that the number of array elements is already known when an object of the template class is instantiated Objects can then be created without allocating dynamic storage
This simplifies the definition of the stack template The copy constructor, the assign-ment operator, and the destructor no longer need to be defined!
䊐 Restrictions
Two restrictions apply to template parameters other than type parameters:
■ they cannot be modified
■ they cannot be floating-point types
The following expression would thus be invalid in the definition opposite:
Example: ++n; // Error: changing template parameter
Even though doubletype template parameters are not permissible,
Example: template<class T, double d> // Error!
class Demo { };
pointers and references to floating-point types are:
Example: template<class T, double& ref>
class Demo { };
Trang 2730 C H A P T E R 3 2 T E M P L A T E S
// mini_t.cpp: Passing arguments to // function templates //
-#include <iostream>
using namespace std;
template <class T>
T min( T x, T y)
{ return( (x < y) ? x : y);
}
int main() {
short x = 10, y = 2;
cout << "x = " << x << " y = " << y << endl; cout << "The smaller value is: "
<< min(x, y) << endl; // Call is ok
double z1 = 2.2;
float z2 = 1.1F;
cout << "\nThe smaller value is: "
<< min(z1, z2) << endl; // Not ok!
double z3 = 1.1;
cout << "\nz1 = " << z1
<< " z3 = " << z3 << endl;
cout << "The smaller value is: "
<< min(z1, z3) << endl; // Call is ok
return 0;
}
■ TEMPLATE ARGUMENTS
Sample program
Trang 3䊐 Passing Arguments
A template is instantiated when a template argument is passed to it The argument types must exactly match to the types of the template parameters
Not even implicit type conversions, such as floattodouble, are performed In the case of the template function min() this means that both arguments must be of the same type The following call
Example: float x = 1.1; double y = 7.7;
min ( x , y );
would lead to an error message, since the template function cannot be defined by the
Prototype: void min( float , double );
䊐 Restrictions
There are several restrictions for template arguments other than type names:
■ if the template parameter is a reference, only a global or static object can be passed as a template argument
■ if the template parameter is a pointer, only the address of an object or a function with global scope can be stated
■ if the template parameter is neither a reference nor a pointer, only constant expressions can be used as template arguments
Example: int cnt = 256; // Error:
typedef Stack<short, cnt> ShortStack;
Since only an intconstant is permitted as a template argument, this statement provokes
an error
Strings, such as "Oktoberfest," are also invalid as template arguments, as their scope is static and not global
Example: template<class T,char* s> class Demo{ };
Only globally defined strings can be used for instantiation, for example
char str[] = "Oktoberfest"; // global
Demo<double, str> income; // ok
Trang 4732 C H A P T E R 3 2 T E M P L A T E S
template <class T>
T min( T x, T y)
{ return( (x < y) ? x : y) }
#include <cstring>
const char* min( const char* s1, const char* s2 )
{ return( (strcmp(s1, s2) < 0 ) ? s1: s2 );
}
#include <cstring>
template<>
const char* min( const char* s1, const char* s2 )
{ return( (strcmp(s1, s2) < 0 ) ? s1: s2 );
}
■ SPECIALIZATION
Function template min()
Specializing the function template for C strings
䊐 ANSI specialization
The ANSI standard does not differ between template functions and “normal” functions The definition of a function template and a function with the same name, which can be generated by the function template, causes the compiler to output an error message (ex
“duplicate definition ”)
That is why the ANSI standard provides its own syntax for defining specializations:
Trang 5䊐 Motivation
A template function can only be instantiated if all the statements contained in the func-tion can be executed If you call the template funcfunc-tion exchange()with two objects of the same class, the copy constructor and the assignment must be defined for this class More specifically, all operators used in a template function must be defined for the current argument type Thus, the function template min(), which determines the lesser
of two arguments, can only be instantiated if the operator < is defined for the argument type
Besides non-executable instructions there are other reasons to prevent a function template being instantiated for a particular type:
■ the generic approach defined by the template does not return any useful results for a given type
■ there are more efficient approaches for some types
The statement
Example: minStr = min(, "VIVIAN", "vivian" );
only returns the lower of the two addresses at which the C strings are stored
䊐 Defining Specialization
In cases like this, it makes sense to specialize the template function definition To do so, you use a function with a separate definition to overload the template function This technique is demonstrated on the opposite page using the function template min(), where a specialization has been defined for the char*type, both for older and more modern compilers that support the current ANSI standard
If a template function is replaced by a specialization, the appropriate version must be executed when a call to the function is made The order the compiler looks up a function guarantees that if both a function template and a specialization are defined for a specific type, the specialization will be called
This also applies to the methods of a class template, which are function templates, of course More specifically, a template class can only be created if all the methods in the appropriate function template can be instantiated without error
Trang 6734 C H A P T E R 3 2 T E M P L A T E S
// quadMat.h: Defines the template QuadMatrix // to represent quadratic matrices //
-#include <iostream>
#include <stdexcept>
using namespace std;
template <class T, int cnt = 10>
class QuadMatrix
{
private:
T mat[cnt][cnt];
public:
int dim() const{ return cnt; }
T* operator[](int line) throw(out_of_range) {
if( line < 0 || line >= cnt) throw out_of_range("Matrix: Index out of range"); else
return mat[line];
}
const T* operator[](int line) const
throw(out_of_range) {
if( line < 0 || line >= cnt) throw out_of_range("Matrix: Index out of range"); else
return mat[line];
} friend QuadMatrix& operator+(const QuadMatrix&,
const QuadMatrix&); // etc
};
■ DEFAULT ARGUMENTS OF TEMPLATES
A class template representing quadratic matrices
Trang 7䊐 Setting Defaults
You can define default arguments for template parameters, just as for function parame-ters If an argument required to instantiate a template is missing, the default value is then used
You can specify default values in the template definition or when you declare a tem-plate in a module
The class template defined opposite, QuadMatrix<T, n>, represents quadratic matri-ces The subscript operator is overloaded to allow you to access a matrix element
m[i][j]in a given matrix m If the line index iis outside of the valid range, a standard
out_of_rangetype exception is thrown
The default values are chosen to create a matrix mforintvalues with 10 rows and 10 columns following this definition:
Example: typedef QuadMatrix < > IntMat;
IntMat m;
You cannot omit the angled brackets since the QuadMatrix type does not exist
QuadMatrixis merely the name of a template
The following definition
Example: typedef QuadMatrix<double> DoubleMat;
DoubleMat dm;
defines a matrix dmofdoublevalues with 10 rows and 10 columns
䊐 Rules
The same rules apply to the default arguments of templates as to the default arguments of functions:
■ if you declare a default argument for at least one parameter, you must define default values for all the remaining parameters
■ if a template argument for which a default argument was declared is omitted dur-ing instantiation, all the remaindur-ing template arguments must be omitted
Trang 8736 C H A P T E R 3 2 T E M P L A T E S
// expIns_t.cpp: Tests explicit instantiation //
-#include <iostream>
#include <iomanip>
using namespace std;
#include "quadMat.h"
// Explicit Instantiation:
template class QuadMatrix<long double, 5>;
int main() {
QuadMatrix<long double, 5> m;
try { for(int k=0; k < m.dim(); k++) {
for( int l = 0; l < m.dim(); l++) {
m[k][l] = k*l;
cout << setw(2) << m[k][l] << " "; }
cout << endl;
} } catch(out_of_range& err ) {
cerr << err.what() << endl;
}
return 0;
}
■ EXPLICIT INSTANTIATION
Sample program for the class template QuadMatrix
Trang 9In addition to implicit instantiation of templates, which occurs when a template func-tion is called, for example, explicit instantiafunc-tion is also possible This is important when you design libraries that contain template functions and classes for application programs
䊐 Syntax
Explicit instantiation can be achieved by the following
Syntax: template declaration;
wheredeclarationcontains the name of the template and the template arguments Explicit instantiation for the class template Stackwould be performed as follows:
Example: template class Stack<long double, 50>;
This declaration creates the template class Stack<long double, 50>with a maxi-mum of 50 long doubletype elements
Function templates can also be instantiated explicitly
Example: template short min( short x, short y);
This creates a template function for the shorttype from the function template min()
䊐 ANSI Instantiation
The ANSI standard provides an additional technique for the explicit instantiation of function templates Template arguments are stated in the angled brackets that follow the function name, when the function is first called
Example: min<long>(x, y);
In this case, a template function min()for the longtype is generated This advanced syntax for function templates is not supported by all C++ compilers, however
Explicit instantiation of function templates extends their possible usage:
■ function templates can be parameterized by types that cannot be derived from the function arguments—more specifically, function templates can be defined with-out function parameters
■ function templates can be defined with function parameters that are not template parameters themselves
Trang 10738 C H A P T E R 3 2 T E M P L A T E S
The left, sorted part originally consists of only one element, the first array element
■ EXERCISES Interpolation search
The elements of a numerical array are assumed to be unique and sorted in ascending order
The given value is compared with the array element at the position where the value is “expected” to be For example, if the value searched for is two-thirds of the way from the lowest to the highest subarray element, the probe would be made two-thirds from the lowest to the highest index of the subarray If the required value is lesser than that of the array element found at the expected position, the search is continued in the left part of the subarray, just like a binary search Otherwise the search continues in the right part of the subarray
The “expected” position expin an array vcan be calculated as follows: If key
is the required value,beginis the lowest, and endis the highest index of the corresponding subarray, the following applies:
double temp = (double)(key-vp[begin]);
temp /= (vp[end]-vp[begin]);
temp = temp * (end - begin) + 0.5;
exp = begin + (int)temp;
Insertion sort algorithm
The following technique is used to divide the array into a left, sorted part and a right, unsorted part:
Each subsequent element in the unsorted part of the array is selected and taken out from the array.As long as a greater array element can be found starting from the end of the left subarray, the element is shifted up by one position If a smaller array element is found, the selected element is inserted at the vacant position
30
30
50
50
70
70
40 20
20
70 > 40? yes
to take out Graphic:
↑