Anda di halaman 1dari 13

Generic Programming

Templates
Class
Templates
Function
Templates


Template code is compiled only when it is
used (template instanciation)
Keyword class (or typename) or int can
be used to qualify template arguments.
Members can be required from template
arguments
Replace virtual functions by mandatory
functions of template arguments
Swapping Values
// swapping of ints
void swap ( int &a , int &b )
{
int c ;
c = a ; a = b ; b = c ;
}
// swapping of floats
void swap ( float &a , float &b )
{
float c;
c = a ; a = b ; b = c ;
}
// swapping of longs
void swap (long &a , long &b )
{
long c ;
c = a ; a = b ; b = c ;
}

void main( )
{
int x = 10 , y = 20 ;
float i = 1.5, j = 2.5 ;
swap ( x , y ) ;
swap ( i, j ) ;
}
Different functions
for different data types
Function Templates
Keyword
Anything
Would do
template < class T >
void swap ( T &a, T &b )
{
T c ;
c = a ; a = b ; b = c ;
}

Only one function
is required
Saves source code disk space
May save EXE spaces
May save memory
void main( )
{
int x = 10, y = 20 ;
float i = 1.5, j = 2.5 ;
swap ( x, y ) ;
swap ( i, j ) ;
}

Multiple Types
template < class T, class U >
void print ( T a, U b )
{
cout << a << endl << b ;
}


void main( )
{
int i = 10 ;
float f = 2.5 ;
print ( i, f ) ;
print ( i, i ) ;
print ( f, f ) ;
}

swap<>( ) from <algorithm>
Usual algorithm, but couched generically (i.e., a
meta-algorithm, applicable to many types):
template< typename T >
inline void swap( T & x, T & y ) {
T const tmp( x ); x = y; y = tmp;
}
Note reliance on Ts concepts (properties):
In above, T must be copyable and assignable
Compile-time enforcement (concept-checking)
techniques available
What Do We Gain
Ease of writing
Type safety
Reduced size
int a = 10 ;
float b = 3.14 ;
swap ( a, b ) ;
Error
Class Templates
Example from <complex>:
template< class T > class complex {
public:
complex( T r, T i ) : realpart(r), imagpart(i) { }
T real() const { return realpart; }
// more member functions
private:
T realpart, imagpart;
};
Usage:
complex< double > c;
Class Template Details
Each function member is a function template:
Each is independently instantiated, iff needed
Its template parameters match those of the class
May have its own (additional) template parameters
Common practice is to publish each class templates
arguments:
template< class T > class Container {
public:
typedef T value_type;
//
};
Class Templates
#include <iostream.h>
const int MAX = 10 ;
template < class T >
class stack
{
private :
T stk [ MAX ] ;
int top ;

public :
stack ( )
{
top = - 1;
}

void push ( T data )
{
if ( top == MAX - 1 )
cout << full ;
else
stk [ ++top ] = data;
}
} ;
void main ( )
{
stack < int > s1 ;
s1.push ( 10 ) ;
s1.push ( 20 ) ;
stack < float > s2 ;
s2.push ( 1.1 ) ;
s2.push ( 2.1 ) ;
}



Stk [ ]
Example
# include <iostream.h>
const int MAX = 10 ;
template < class T >
class stack
{
protected :
T stk[ MAX ];
int top ;
public :
stack ( )
{
top = -1 ;
}
void push ( T data )
{
if ( top == MAX- 1 )
cout << full ;
else
stk [ ++top ] = data ;
}
} ;
template < class T >
class stack1 : public stack < T >
{
public :
T pop( )
{

if ( top == - 1 )
{
cout << Empty ;
return -1 ;
}
return stk[ top- - ] ;
}
} ;
void main( )
{
stack1 <int > s1 ;
s1.push ( 10 ) ;
cout << s1.pop( ) ;
}
Unlike Function Templates
Class template arguments cant be deduced in the same
way, so usually written explicitly:
complex <double> c;
Class template parameters may have default values:
template< class T, class U = int >
class MyCls { };
Class templates may be partially specialized:
template< class U >
class MyCls< bool, U > { };
Generic Programming Pitfalls
Extra thought is necessary when designing generic
components:
template< typename X, typename Y > // No!
void swap( X & x, Y & y ) {
X const tmp( x ); x = y; y = tmp;
}
Relies on X Y conversion concepts:
Post-swap() values need not match original values
Hence, swap() twice cant always restore originals
Such counter-intuitive behavior ought be avoided

Anda mungkin juga menyukai