0% found this document useful (0 votes)
49 views22 pages

Templates

This document discusses templates in C++. It explains that templates allow code reuse for different data types by using a template argument that can represent any type. Function templates define a function using a template argument rather than a specific type, and the compiler generates versions of the function for each type used. Class templates similarly allow defining reusable container classes that can store different data types. Templates increase code reuse and avoid bugs by defining functions and classes only once rather than separately for each type.

Uploaded by

meraj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
49 views22 pages

Templates

This document discusses templates in C++. It explains that templates allow code reuse for different data types by using a template argument that can represent any type. Function templates define a function using a template argument rather than a specific type, and the compiler generates versions of the function for each type used. Class templates similarly allow defining reusable container classes that can store different data types. Templates increase code reuse and avoid bugs by defining functions and classes only once rather than separately for each type.

Uploaded by

meraj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 22

OOP

TEACHER: SHER AFGUN USMANI


Templates
Templates

 C++ supports code reuse in different ways.

 Thetemplate feature in C++ provides way to reuse


source code.

 The concept of Template is applicable to:


 Functions

 Classes
Function Templates

 Suppose we want to write a function that returns the absolute value


of a number.

 Ordinarily, this function would be written for a particular data type:


int abs(int n) // absolute value of ints
{
return (n<0) ? -n : n; // if n is negative, return –n
}

 Here the function is defined to take an argument of type int and to


return a value of this same type.
Function Templates

 But now suppose we want to find the absolute value of a type long.
 We need to write a completely new function:
long abs(long n) // absolute value of longs
{
return (n<0) ? -n : n;
}

 And again, for type float:


float abs(float n) // absolute value of floats
{
return (n<0) ? -n : n;
}
Function Templates

 The body of the function is same in each case, but they must be
separate functions because they handle variables of different
types.

 It’s true that in C++ these functions can all be overloaded to


have the same name, but we must nevertheless write a separate
definition for each one.

 Rewriting the same function body over and over for different
types wastes time as well as space in the listing.
Function Templates

 Also, if we find we’ve made an error in one such function, we’ll


need to remember to correct it in each function body.

 Failing to do this correctly is a good way to introduce


inconsistencies into our programs.

 It would be nice if there were a way to write such a function just


once and have it work for many different data types.

 This is exactly what Function templates do for us.


Function Templates
template <class T> // function template
T abs(T n)
{ return (n < 0) ? -n : n; }
void main() { OUTPUT
int int1 = 5; abs(5)=5
int int2 = -6;
abs(-6)=6
long long1 = 70000;
abs(70000)=70000
long long2 = -80000;
double dub1 = 9.95; abs(-80000)=80000
double dub2 = -10.15; abs(9.95)=9.95
cout << "abs(" << int1 << ")=" << abs(int1) << endl; // abs(int) abs(-10.15)=10.15
cout << "abs(" << int2 << ")=" << abs(int2) << endl; // abs(int)
cout << "abs(" << long1 << ")=" << abs(long1) << endl; // abs(long)
cout << "abs(" << long2 << ")=" << abs(long2) << endl; // abs(long)
cout << "abs(" << dub1 << ")=" << abs(dub1) << endl; // abs(double)
cout << "abs(" << dub2 << ")=" << abs(dub2) << endl; // abs(double)
}
Function Templates

 The key innovation in function templates is to represent the data


type used by the function not as a specific type such as int, but by
a name that can stand for any type.
 In the function template above, this name is T.
 The template keyword signals the compiler that we are about to
define a Function template.
 The keyword class, within the angle brackets, might just as well
be called type.
 As we’ve seen, we can define our own data types using classes,
so there’s really no distinction between types and classes.
 The variable following the keyword class (T in this example) is
called the template argument.
Function Templates

 What does the compiler do when it sees the template keyword


and the Function definition that follows it?
 The function template itself doesn’t cause the compiler to
generate any code.
 It can’t generate code because it doesn’t know yet what data
type the function will be working with.
 It simply remembers the template for possible future use.
 Code generation doesn’t take place until the function is actually
called (invoked) by a statement within the program.
 This happens in expressions such as abs(int1) in the statement
 cout << "abs(" << int << ")=" << abs(int1);
Function Templates

 When the compiler sees a function call, it knows that the type to
use is int, because that’s the type of the argument int1.

 So it generates a specific version of the abs() function for type


int, substituting int wherever it sees the name T in the function
template.

 This is called instantiating the function template, and each


instantiated version of the function is called a template function.
Function Templates

 Notice that the amount of RAM used by the program is the same
whether we use the template approach or write three separate
functions.
 What we’ve saved is having to type three separate functions into
the source file. This makes the listing shorter and easier to
understand.
 Also, if we want to change the way the function works, we need
to make the change in only one place in the listing instead of
three.
Function Templates with Multiple
Arguments
 Let’s look at another example of a function template.
 This one takes three arguments: two template arguments and
one basic type.
 The purpose of this function is to search an array for a specific
value.
 The function returns the array index for that value if it finds it,
or -1 if it can’t find it.
 The arguments are a pointer to the array, the value to search for,
and the size of the array.
Function Templates with Multiple Arguments
template <class atype>
int find(const atype* array, atype value, int size) {
for(int j=0; j<size; j++)
Output
if(array[ j ]==value) return j;
'f' in chrArray: index=2
return -1;
6 in intArray: index=-1
}
4 in dubArray: index=-1
int main() {
char chrArr[ ] = {'a', 'c', 'f', 's', 'u', 'z'}; // array
char ch = 'f'; // value to find
int intArr[ ] = {1, 3, 5, 9, 11, 13};
int in = 6;
double dubArr[ ] = {1.0, 3.0, 5.0, 9.0, 11.0, 13.0};
double db = 4.0;
cout << "\n 'f' in chrArray: index=" << find(chrArr, ch, 6);
cout << "\n 6 in intArray: index=" << find(intArr, in, 6);
cout << "\n 4 in dubArray: index=" << find(dubArr, db, 6);
return 0;
}
Template Arguments Must Match

 When a template function is invoked, all instances of the same


template argument must be of the same type.
 For example, in find(), if the array is of type int, the value to
search for must also be of type int. We can’t say
int intarray[ ] = {1, 3, 5, 7}; // int array
float f1 = 5.0; // float value
int value = find(intarray, f1, 4); // error
 Because the compiler expects all instances of atype to be the
same type.
find(int*, int, int); // It can generate a function
find(int*, float, int); // It can’t generate a function
 Because the first and second arguments must be the same type.
Class Templates

 The template concept can be applied to classes as well as to


functions.

 Class templates are generally used for data storage (container)


classes.

 Stacks and linked lists, are examples of data storage classes.


Class Templates

 The Stack class below, could store data only of type int.

class Stack
{
int st[10]; // array of ints
int top; // index number of top of stack
public:
Stack(); // constructor
void push(int var); // takes int as argument
int pop(); // returns int value
};
Class Templates

 If we wanted to store data of type long in a stack, we would need to define a


completely new class.

class LongStack
{
long st[10]; // array of longs
int top; // index number of top of stack
public:
LongStack(); // constructor
void push(long var); // takes long as argument
long pop(); // returns long value
};
Class Templates

//Solution with a class template


template <class Type>
class Stack{
Type st[10]; // stack: array of any type
int top; // number of top of stack
public:
Stack(){top = 0;} // constructor
void push(Type); // put number on stack
Type pop(); // take number off stack
};
Class Templates

template<class Type>
void Stack<Type>::push(Type var) // put number on stack
{ if(top > 10-1) // if stack full,
cout<< "Stack is full!";
st[top++] = var;
}

template<class Type>
Type Stack<Type>::pop() // take number off stack
{ if(top <= 0) // if stack empty,
cout<< "Stack is empty!";
return st[--top];
}
Class Template
int main() {
Stack<float> s1; // s1 is object of class Stack<float>
// push 2 floats, pop 2 floats
s1.push(1111.1);
s1.push(2222.2);
cout << "1: " << s1.pop() << endl;
cout << "2: " << s1.pop() << endl;

Stack<long> s2; // s2 is object of class Stack<long>


// push 2 longs, pop 2 longs
s2.push(123123123L);
s2.push(234234234L);
cout << "1: " << s2.pop() << endl;
cout << "2: " << s2.pop() << endl;
return 0;
}
Questions?

You might also like