1
Chapter 11 - Templates
Outline 11.1 11.2 11.3 11.4 11.5 11.6 11.7 11.8 Introduction Function Templates Overloading Function Templates Class Templates Class Templates and Nontype Parameters Templates and Inheritance Templates and Friends Templates and static Members
2003 Prentice Hall, Inc. All rights reserved.
11.1 Introduction Templates
Function templates
Specify entire range of related (overloaded) functions Function-template specializations
Class templates
Specify entire range of related classes Class-template specializations
2003 Prentice Hall, Inc. All rights reserved.
11.2 Function Templates Overloaded functions
Similar operations
Different types of data
Function templates
Identical operations
Different types of data
Single function template
Compiler generates separate object-code functions
Type checking
2003 Prentice Hall, Inc. All rights reserved.
11.2 Function Templates Function-template definitions
Keyword template List formal type parameters in angle brackets (< and >)
Each parameter preceded by keyword class or typename class and typename interchangeable template< class T > template< typename ElementType > template< class BorderType, class FillType > Specify types of Arguments to function Return type of function Variables within function
2003 Prentice Hall, Inc. All rights reserved.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// Fig. 11.1: fig11_01.cpp // Using template functions. #include <iostream> using std::cout; using std::endl;
Outline
fig11_01.cpp (1 of 2)
// function template printArray template< class T > void printArray( const T *array, const int count ) { T is type parameter; use any for ( int i = 0; i < count; i++ ) cout << array[ i ] <<valid " ";identifier. cout << endl; } // end function
Function template definition; declare single formal type definition parameter T.
int main() { const int aCount = 5; const int bCount = 7; const int cCount = 6;
If T is user-defined type, stream-insertion operator printArray must be overloaded for class T.
2003 Prentice Hall, Inc.
All rights reserved.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
int a[ aCount ] = { 1, 2, 3, 4, 5 }; double b[ bCount ] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 }; char c[ cCount ] = "HELLO"; // 6th position for null cout << "Array a contains:" << endl; // call integer function-template specialization printArray( a, aCount );
Outline
fig11_01.cpp (2 of 2)
Compiler infers T is double; instantiates function-template Creates complete function-template specialization for printing // call double function-template specialization where T is of ints: printArray( b, bCountarray ); specialization double. infers T is int char ; void Compiler printArray( const *array, const int count ) cout << "Array c contains:" << endl; { instantiates function-template for ( int i = 0; i < T count; i++ ) specialization where is // call character function-template specialization cout << array[ i ] << " " printArray( c, cCount ); char cout << . endl;
cout << "Array b contains:" << endl; } // end function printArray
return 0; } // end main
2003 Prentice Hall, Inc.
All rights reserved.
Array a 1 2 3 4 Array b 1.1 2.2 Array c H E L L
contains: 5 contains: 3.3 4.4 5.5 6.6 7.7 contains: O
Outline
fig11_01.cpp output (1 of 1)
2003 Prentice Hall, Inc.
All rights reserved.
11.3 Overloading Function Templates Related function-template specializations
Same name
Compiler uses overloading resolution
Function template overloading
Other function templates with same name
Different parameters
Non-template functions with same name
Different function arguments
Compiler performs matching process
Tries to find precise match of function name and argument types If fails, function template Generate function-template specialization with precise match
2003 Prentice Hall, Inc. All rights reserved.
11.4 Class Templates Stack
LIFO (last-in-first-out) structure
Class templates
Generic programming Describe notion of stack generically
Instantiate type-specific version
Parameterized types
Require one or more type parameters Customize generic class template to form class-template specialization
2003 Prentice Hall, Inc. All rights reserved.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// Fig. 11.2: tstack1.h // Stack class template. #ifndef TSTACK1_H #define TSTACK1_H template< class T > class Stack { public: Stack( int = 10 );
10
Outline
Specify class-template definition; type parameter T indicates type of Stack class to be created. tstack1.h (1 of 4)
// default constructor (stack size 10)
// destructor ~Stack() { delete [] stackPtr; } // end ~Stack destructor bool push( const T& ); bool pop( T& ); // push an element onto the stack // pop an element off the stack
Function parameters of type T.
2003 Prentice Hall, Inc.
All rights reserved.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
// determine whether Stack is empty bool isEmpty() const { return top == -1; } // end function isEmpty // determine whether Stack is full bool isFull() const { return top == size - 1; } // end function isFull private: int size; int top; T *stackPtr;
11
Outline
tstack1.h (2 of 4)
Array of elements of type T.
// # of elements in the stack // location of the top element // pointer to the stack
}; // end class Stack
2003 Prentice Hall, Inc.
All rights reserved.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
// constructor template< class T > Stack< T >::Stack( int s ) Constructor creates array of type { For example, compiler generates size = s > 0 ? s : 10; top = -1; // Stack initially empty stackPtr = new T[ size ]; stackPtr = new T[ size ]; // allocate memory for elements } // end Stack constructor
12
Outline
T. tstack1.h (3 of 4)
// push element onto stack; // if successful, return true; template< class T > bool Stack< T >::push( const T { if ( !isFull() ) { stackPtr[ ++top ] = pushValue; // place item on Stack return true; // push successful } // end if return false; // push unsuccessful
Member functions preceded for class-template specialization with header Stack< double >. Use binary scope resolution operator (return ::) template< with class- class T > otherwise, false template name (Stack< T >) to tie definition to class &pushValue ) templates scope.
} // end function push
2003 Prentice Hall, Inc.
All rights reserved.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
// pop element off stack; // if successful, return true; otherwise, return false template< class T > bool Stack< T >::pop( T &popValue ) { Member function preceded if ( !isEmpty() ) { with header popValue = stackPtr[ top-- ]; // remove item from Stack return true; // pop successful template< class T > Use binary scope resolution
13
Outline
tstack1.h (4 of 4)
} // end if
return false; // pop unsuccessful
operator (::) with classtemplate name (Stack< T >) to tie definition to class templates scope.
} // end function pop #endif
2003 Prentice Hall, Inc.
All rights reserved.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// Fig. 11.3: fig11_03.cpp // Stack-class-template test program. #include <iostream> using std::cout; using std::cin; using std::endl; #include "tstack1.h"
14
Outline
fig11_03.cpp (1 of 3)
Link to class template definition.
// Stack class template definition
int main() { Stack< double > doubleStack( 5 ); double doubleValue = 1.1; cout << "Pushing elements onto
Instantiate object of class Stack< double >.
Invoke function push of class-template specialization doubleStack\n"; Stack< double >.
while ( doubleStack.push( doubleValue ) ) { cout << doubleValue << ' '; doubleValue += 1.1; } // end while cout << "\nStack is full. Cannot push " << doubleValue << "\n\nPopping elements from doubleStack\n";
2003 Prentice Hall, Inc.
All rights reserved.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
15
while ( doubleStack.pop( doubleValue ) ) cout << doubleValue << ' '; cout << "\nStack is empty. Cannot pop\n";
Outline
Invoke function pop of classtemplate specialization Stack< double >. fig11_03.cpp (2 of 3)
Stack< int > intStack; int intValue = 1; cout << "\nPushing elements onto intStack\n"; while ( intStack.push( intValue ) ) { cout << intValue << ' '; ++intValue; } // end while
Note similarity of code for Stack< int > to code for Stack< double >.
cout << "\nStack is full. Cannot push " << intValue << "\n\nPopping elements from intStack\n"; while ( intStack.pop( intValue ) ) cout << intValue << ' ';
cout << "\nStack is empty. Cannot pop\n";
return 0;
2003 Prentice Hall, Inc.
All rights reserved.
51 52
16
} // end main
Outline
fig11_03.cpp (3 of 3) fig11_03.cpp output (1 of 1)
Pushing elements onto doubleStack 1.1 2.2 3.3 4.4 5.5 Stack is full. Cannot push 6.6 Popping elements from doubleStack 5.5 4.4 3.3 2.2 1.1 Stack is empty. Cannot pop Pushing elements onto intStack 1 2 3 4 5 6 7 8 9 10 Stack is full. Cannot push 11 Popping elements from intStack 10 9 8 7 6 5 4 3 2 1 Stack is empty. Cannot pop
2003 Prentice Hall, Inc.
All rights reserved.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
// Fig. 11.4: fig11_04.cpp // Stack class template test program. Function main uses a // function template to manipulate objects of type Stack< T >. #include <iostream> using std::cout; using std::cin; using std::endl;
17
Outline
fig11_04.cpp (1 of 2)
#include "tstack1.h"
// Stack class template definition
// function template to manipulate Stack< T > template< class T > void testStack( Stack< T > &theStack, // reference to Stack< T > T value, // initial value to push T increment, // increment for subsequent values const char *stackName ) // name of the Stack < T > object { cout << "\nPushing elements onto " << stackName << '\n'; while ( theStack.push( value ) ) { cout << value << ' '; value += increment; } // end while
Function template to manipulate Stack< T > eliminates similar code from previous file for Stack< double > and Stack< int >.
2003 Prentice Hall, Inc.
All rights reserved.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
18
cout << "\nStack is full. Cannot push " << value << "\n\nPopping elements from " << stackName << '\n'; while ( theStack.pop( value ) ) cout << value << ' '; cout << "\nStack is empty. Cannot pop\n";
Outline
fig11_04.cpp (2 of 2)
} // end function testStack
int main() { Stack< double > doubleStack( 5 ); Stack< int > intStack; testStack( doubleStack, 1.1, 1.1, "doubleStack" ); testStack( intStack, 1, 1, "intStack" ); return 0; } // end main
2003 Prentice Hall, Inc.
All rights reserved.
Pushing elements onto doubleStack 1.1 2.2 3.3 4.4 5.5 Stack is full. Cannot push 6.6 Popping elements from doubleStack 5.5 4.4 3.3 2.2 1.1 Stack is empty. Cannot pop Pushing elements onto intStack 1 2 3 4 5 6 7 8 9 10 Stack is full. Cannot push 11 Popping elements from intStack 10 9 8 7 6 5 4 3 2 1 Stack is empty. Cannot pop
19
Outline
fig11_04.cpp output (1 of 1)
Note output identical to that of fig11_03.cpp.
2003 Prentice Hall, Inc.
All rights reserved.
20
11.5 Class Templates and Nontype Parameters Class templates
Nontype parameters
Default arguments Treated as consts Example: template< class T, int elements > Stack< double, 100 > mostRecentSalesFigures; Declares object of type Stack< double, 100>
Type parameter
Default type Example: template< class T = string >
2003 Prentice Hall, Inc. All rights reserved.
21
11.5 Class Templates and Nontype Parameters Overriding class templates
Class for specific type
Does not match common class template
Example:
template<> Class Array< Martian > { // body of class definition };
2003 Prentice Hall, Inc. All rights reserved.
22
11.6 Templates and Inheritance Several ways of relating templates and inheritance
Class template derived from class-template specialization Class template derived from non-template class Class-template specialization derived from class-template specialization Non-template class derived from class-template specialization
2003 Prentice Hall, Inc. All rights reserved.
23
11.7 Templates and Friends Friendships between class template and
Global function Member function of another class Entire class
2003 Prentice Hall, Inc. All rights reserved.
24
11.7 Templates and Friends friend functions
Inside definition of template< class T > class X
friend void f1(); f1() friend of all class-template specializations friend void f2( X< T > & ); f2( X< float > & ) friend of X< float > only, f2( X< double > & ) friend of X< double > only, f2( X< int > & ) friend of X< int > only,
friend void A::f4(); Member function f4 of class A friend of all class-template specializations
2003 Prentice Hall, Inc. All rights reserved.
25
11.7 Templates and Friends friend functions
Inside definition of template< class T > class X
friend void C< T >::f5( X< T > & ); Member function C<float>::f5( X< float> & ) friend of class X<float> only
friend classes
Inside definition of template< class T > class X
friend class Y; Every member function of Y friend of every class-template specialization friend class Z<T>; class Z<float> friend of class-template specialization X<float>, etc.
2003 Prentice Hall, Inc. All rights reserved.
26
11.8 Templates and static Members Non-template class
static data members shared between all objects
Class-template specialization
Each has own copy of static data members static variables initialized at file scope Each has own copy of static member functions
2003 Prentice Hall, Inc. All rights reserved.