Templates &
Generic Programming
Generic Programming
Algorithms are written independently of
data
data types are filled in during execution
functions or classes instantiated with data
types
formally known as specialization
Also used in Metaprogramming
Lets motivate ourselves
Number of algorithms are data-type
independent
sorting
searching
finding n-th largest
swapping etc
Write once, use many times philosophy
dramatically reduces LOC (lines-of-code)
In C++
Templates = generic programming Two types
function templates
special functions that can operate with generic
types.
class templates
can have members that use template parameters
Motivation
Motivation
• A function for finding minimum value
• For floats we will need another function
• Can we parameterize this function with a typetype?
– Towards GenericGeneric Programming
– Like objects are generalized into classes, we would like to generalize classes and functions into templatestemplates
int min(int a, int b){
return (a<b ? a : b)
}
float min(float a, float b){ return (a<b ? a : b)
void swap(int& a, int& b){ int temp = a;
a = b; b = temp; }
void swap(char& a, char& b){ char temp = a;
a = b; b = temp; }
void swap(float& a, float& b){ float temp = a;
a = b; b = temp; }
void swap(short& a, short& b){ short temp = a;
a = b; b = temp; }
void swap(boolean& a, boolean& b){ boolean temp = a;
a = b; b = temp; }
void swap(double& a, double& b){ double temp = a;
a = b; b = temp; }
void swap(string& a, string& b){
string temp = a; a = b;
b = temp;
} void swap(Parrot& a, Parrot& b){ Parrot temp = a;
a = b; b = temp; }
void swap(Cat& a, Cat& b){ Cat temp = a;
a = b; b = temp; }
void swap(Elephant& a, Elephant& b){ Elephant temp = a;
a = b; b = temp; }
void swap(Snake& a, Snake& b){ Snake temp = a;
a = b; b = temp;
} void swap(Crocodile& a, Crocodile& b){ Crocodile temp = a;
a = b; b = temp; }
void swap(Eagle& a, Eagle& b){ Eagle temp = a;
a = b; b = temp; }
Motivation
Templates
Templates
• C++ provides a super macro mechanismsuper macro mechanism that is identified by the keyword templatetemplate
• TemplatesTemplates can be thought of as MACROMACROs for functions
functions and classesclasses, that need not be explicitly called by the programmer
• TemplatesTemplates are controlled by the compilercompiler (and not by the pre-processorpre-processor)
• Templates argumentsTemplates arguments are either class-types or
const-expressions of a fixed type
Function Template
Function Template
• Preserving the semantics of a function
• Automatically generatedAutomatically generated instance of a function, varying by type
• The programmer parameterizes all or a subset of the types in the interface
• The function implementation remains invariantinvariant over a set of function instancesfunction instances, each handling a unique data typeunique data type
template <class Type>
Type min(Type a, Type b) { return ( a>b ? a : b);
Function Temples Cont.
Function Temples Cont.
Template
Template <calss calss T>T T
T min(TT a, TT b){
return (a<b ? a : b) }
operator< should be defined for calss T Declaration
int main()
{ intint a=3, b=4;
charchar c= ‘a’, d = ‘b’;
cout << min(a,b); // o.k
cout << min(c,d); // o.k
cout << min(a,c); // Error!!
return 0;
Usage
Defining additional function
int min(int, int)
Function Temples Cont.
Function Temples Cont.
• For each calleach call to a function template, the compiler will try to generate an actual functiongenerate an actual function with the
appropriate prototype
• OverloadingOverloading for function of the same name is done in this order:
– Look for an exactexact match among non-template functions – Look for an exactexact match that can be generated from
function template
– Look for the best match non-template functions, using
1. Trivial conversion
2. Promotions (e.g. short to int)
3. Standard conversions (e.g. int to double)
Function Templates Cot..
Function Templates Cot..
special functions using template types.
A template parameter is a special kind of
parameter used to pass a type as argument
just like regular function parameters
Declaration Format?
format for declaring function templates
with type parameters
template <class identifier> function_
declaration;
template <typename identifier> function_
declaration;
Same functionality, different keywords
use <typename ...>
Example
create a template function that returns
the greater one of two objects
template <typename myType>
myType GetMax (myType a, myType b) {
Usage
int main () {
int i=5, j=6, k; long l=10, m=5, n;
k=GetMax<int>(i,j); n=GetMax<long>(l,m);
cout << k << endl; cout << n << endl; return 0;
}
int main () {
int i=5, j=6, k; long l=10, m=5, n;
k=GetMax(i,j); n=GetMax(l,m);
cout << k << endl; cout << n << endl; return 0;
Usage
int main () {
int i=5, j=6, k; long l=10, m=5, n;
k=GetMax(i,l); n=GetMax(j,m); }
One template type only in definition
Multiple template types
define template types after the template
keyword
template <typename T1, typename T2> myType GetMax (T1 a, T2 b)
{
return (a>b?a:b); }
no difference in function call
Class Templates
Class Templates
•
Class templates
Class templates
are used to define generic
classes
• An
actual class
actual class
is created only when an
actual object defined, using the class
template with actual parameters
templete
templete<classclass E, intint size> classclass Buffer;
Buffer
Buffer<char*char*, 1024> buf_chrp; Buffer
• templetetemplete<classclass E, intint size> classclass
Buffer
• { T array[size];}; • Main()
{ BufferBuffer<char*char*, 1024> buf_chrp;
Buffer<Buffer int, int 1024> buf_int;}
Mean:
• Class Buffer{ int array[1024]; • char * a;
Class templates
classes can have members that use
template parameters as type
template <class T> class mypair {
T values [2]; public:
mypair (T first, T second) {
values[0]=first; values[1]=second; }
To use
stores two elements of any valid type to store two integer values of type int
with the values 115 and 36:
mypair<int> myobject (115, 36);
to store two doubles:
Non-inline definition
to define a function member outside the
declaration of the class template, always precede that definition with the template <...> prefix
template <class T> class mypair {
T values [2]; public:
mypair (T first, T second) {
values[0]=first; values[1]=second; }
Continued
template <class T>T mypair<T>::getmax () {
T retval;
retval = a>b? a : b; return retval;
}
int main () {
mypair <int> myobject (100, 75); cout << myobject.getmax();
Why so many T's??
There are three T's in this declaration first one is the template parameter.
second T refers to the type returned by
the function
third T (the one between angle brackets)
Specialization
Why and what?
to define a different implementation for a template when a specific type is passed as template parameter
explicitly declare a specialization of that
Sample Case
A class with a sort method
sorts ints, chars, doubles, floats
also need to sort strings based on length, but the algorithm is different
not lexicographic sorting
Need to explicitly create template
Code
template <class T> class MyContainer { T element[100]; public:
MyContainer( T *arg ){...}; void Sort() {
// use your favorite sorting algorithm }
Code
// class template specialization: template <>
class MyContainer <string> { string element[100];
public:
MyContainer (string *arg) {...} void Sort() {
// use a string-length based sort here }
Non-type parameters?
templates can also have regular typed
parameters, similar to those found in functions
template <class T, int N> class mysequence {
T memblock [N]; public:
void setmember (int x, T value); T getmember (int x);
Continued
template <class T, int N>
T mysequence<T,N>::getmember (int x) { return memblock[x];
}
int main () {
mysequence <int,5> myints;
mysequence <double,5> myfloats; myints.setmember (0,100);
myfloats.setmember (3,3.1416);
cout << myints.getmember(0) << '\n'; cout << myfloats.getmember(3) << '\n'; return 0;
22.3 Class Templates and Non-type Parameters
Can use non-type parameters in templates Default argument
Treated as const
Example:
template< class T, int elements >
Stack< double, 100 > mostRecentSalesFigures;
Declares object of type Stack< double, 100>
This may appear in the class definition:
T stackHolder[ elements ]; //array to hold stack
22.3 Class Templates and Non-type Parameters (II)
Classes can be overridden
For template class Array, define a class named Array<myCreatedType>
This new class overrides then class template for
myCreatedType
22.4 Templates and Inheritance
A class template can be derived from a template class
A class template can be derived from a non-template class
A template class can be derived from a class template
22.5 Templates and friends
Friendships allowed between a class template and
Global function
Member function of another class Entire class
friend functions
Inside definition of class template X: friend void f1();
f1() a friend of all template classes
friend void f2( X< T > & );
f2( X< int > & ) is a friend of X< int > only. The same applies for float, double, etc.
friend void A::f3();
22.5 Templates and friends (II)
friend void C< T >::f4( X< T > & );
C<float>::f4( X< float> & ) is a friend of class X<float> only
friend classes friend class Y;
Every member function of Y a friend with every template class made from X
friend class Z<T>;
22.6 Templates and static Members
Non-template class
static data members shared between all objects
Template classes
Each class (int, float, etc.) has its own copy of static data
members
static variables initialized at file scope
Each template class gets its own copy of static member