|
|||||
CS201
Introduction to Programming
Lecture
Handout
Introduction
to Programming
Lecture
No. 41
Reading
Material
Deitel
& Deitel - C++ How to
Program
Chapter.
12
12.2,
12.3
Summary
63)
Template
Functions
64)
Overloading Template
Functions
65)
Explicitly
Specifying the Type in a Template
Function
66)
Template
Functions and Objects
67)
Recap
In the
previous lecture, we talked about the
objects used as data members
within classes.
In this
case, you will find
that there is a lot of code
reuse. A completely debug
code is
used as
building blocks for developing new
and more complex classes.
Today's
discussion
will mainly focus on a new
way of code reuse with an
entirely different style
of reuse.
This method is called
templates.
Template
Functions
There
are two different types of
templates in C++ language
i.e.' function templates
and
class
templates. Before going ahead, it will be
sagacious to know what a
template is? You
have
used a lot of templates in
the childhood. There are
small scales being marketed
at
the
stationary shops having some figures on
them like circle, a square,
rectangle or a
triangle. We
have been using these
articles to draw these shapes on
the paper. We put the
scale on
the paper and draw
the lines with the pencil
over that figure to get
that shape.
These
engraved shapes are generally called
stencils. But in a way, these
are also
templates.
We may also take these
`cut-outs' as sketches. So a template is
a sketch to
draw
some shape or figure. While
drawing a special design,
say of furniture, we
develop
a template
for this, which is not an
actual piece of furniture. We
try that its shape
should
be like
the outline. Later, the cut
out prepared out of wood in
line with the template,
is
actual
piece of furniture. We can
think of making a triangular template
and then drawing
it on a
piece of wood and shaping it
into a triangle. We can use
the same template and
put
it on a
piece of metal and can cut it
into a triangle and so on. In a
way, that template is
Page
527
CS201
Introduction to Programming
allowing
us the reuse of a certain
shape. This is the concept
we are going to try and
build
on
here.
Here we
are going to discuss the
benefits of the function
templates. We have been using
a
swap
function.
We want to interchange two things.
You know the technique
that we need
a third
temp-place holder. If we want to swap
two integers i
and
j, the
code will be as
under:
void
swap(int &i, int &j)
{
int
tmp;
tmp =
i;
i =
j;
j =
tmp;
}
This is a
very generic way of interchanging
two values. We have written
a swap function
to
interchange two integers. To
interchange two doubles, we
have to come up with
some
other
swap function for doubles
and so on. Whenever, a need
to use this swapping
technique
for different data type
arises, we have to write a
new function. Can we
write
such
functions? Yes, we can. These functions
can be overloaded. We can
have functions
with
the same name as long as
the types or the number or
the arguments are
different.
Compiler
can detect which function
should be used. It will call
that function
appropriately. So
you can define swap
for
integers, floats and doubles.
There is also no
problem in
defining multiple versions of
this function with different
data types.
Depending
on what is required, the
compiler will automatically
make a call to the
correct
function.
This is the overloading. The
code for every data
type looks like:
void
swap(SomeDataType &firstThing,
SomeDataType &secondThing)
{
SomeDataType
tmp;
tmp =
firstThing;
firstThing
= secondThing;
secondThing
= tmp;
}
This is a
sort of generic code, we are
writing again and again
for different data types.
It
will be
very nice if somehow we can write
the code once and
let the compiler or
language
handle
everything else. This way of
writing is called templates or function
templates. As
seen in
the example of a template of a triangle, we
will define a generic function.
Once it
is
defined and determined where it
will be called for some
specific data type,
the
compiler
will automatically call that
function.
As
discussed in the example of overloaded
functions, the automatic part is also
there.
But we
wrote all those functions
separately. Here the automatic part is
even deeper. In
other
words, we write one template
function without specifying a
data type. If it is to be
Page
528
CS201
Introduction to Programming
called
for int
data
type, the compiler will
itself write an int
version of
that function. If it is
to be called
for double, the compiler
will itself write it.
This does not happen at
run time,
but at
compile time. The compiler
will analyze the program and
see for which data
type,
the
template function has been
called. According to this, it will get
the template and
write
a
function for that data
type.
Now, we
will see the idea or
technique for defining
template function. Here you
will
come
across some new keywords.
First keyword is "template". These
are the recent
addition to
the language. Some old
compilers may not have
these features. However,
now
almost
all of the compilers
implement these features.
Another keyword is class
that
is
quite
different than we have been
using for defining the
classes. This is another use
of the
same
keyword. Normally, when we define a
generic function, it is independent of
the
data
type. The data type will be
defined later in the program
on calling this function.
The
first
line will be as template<generic
data type>. This
generic data type is written
while
using
the class
key
word as template<class
variable_name>. So the
first line will be
as;
template<class
T>
We generally
use the variable name as T
(T
evolves from template). However, it is
not
something
hard and fast. After
the variable name, we start
writing the function
definition.
The
function arguments must contain at least
one generic data type.
Normal function
declaration
is:
return_type
function_name(argument_list)
return_type
can
also be of generic type. There
should be at least an argument of
generic
type in
the argument_list. Let's
take a very simple example.
This is the function reverse.
It takes
one argument and returns
its minus version. The int
version of
this function is as:
int
reverse(int x)
{
return
(-x);
}
Similarly
its double version will be
as:
double
reverse(double x)
{
return
(-x);
}
Similarly,
we can define it for other
data types.
Let's
see how can we make a
template of this function. The
code is as:
template<class
T>
Page
529
CS201
Introduction to Programming
T
reverse(T x)
{
return
(-x);
}
In the
above function definition, we
have used T
as
generic type. The return type of
the
function
is T
which is
accepting an argument of type T. In the
body of the function, we
just
minus it and return x
that is
of type T. Now in
the main program, if we write it as
int
i
and
then call reverse(i),
what will
happen? The compiler will
automatically detect that i
is an int
and
reverse
is a
template function. So, an int
version of
reverse
function
is
needed in
the program. It uses the
template to generate an int
version.
How does it do
that? It
replaces the T
with
int
in
the template function. You
will get exactly the
same
function
as we have written before as
int
reverse(int x). This copy
is generated at compile
time.
After the compilation, all
the code is included in the
program. A normal
function
call
will happen. When we write
reverse(i)
in
the main or some other
function, it is not
required
to tell that an int
version is
needed. The compiler will
automatically detect
the
data type
and create a copy of the
function of the appropriate
data type. This is
important
to
understand. Similarly if we have
double
y; and we
call the reverse
function
as
reverse(y); the
compiler will automatically
detect that this program is
calling reverse(i)
and
reverse(y).
Here i is an int
and in
reverse(y),
y is
a double. So the
compiler will
generate
two versions of reverse
function,
one with int
and
the other with double. Then
it
will be
compiled and the program
will execute correctly. This is
the classic example of
code
reuse. We have to pay
attention to writing the
template. It should be generic
in
nature.
For a
programmer, there are facilities of
the macros and #define
which
have the
limitations.
Macro is a code substitution while
#define
is a
value substitution. Here, in
templates,
we write a generic code and
the compiler generates its
copies of appropriate
types. It
is always better than ordinary
function overloading. Now let's
take the previous
example of
reverse. When we
write the function of reverse
and
give it a value of
type
double, a version of
the reverse
function
for double
is
created, compiled and used.
If we
write
the same template in some
other program and call it
for an integer, it will
still work.
It will
automatically generate code
for int. We
should write a template while doing
the
same
functionality with different
data types. The rule for
templates is that at least
one
argument
in the function should be of
generic data type. Other
wise, it is not a
template
function.
We write a template class
T and
use T
as a
new data type. Being a
template data
type, it
does not really exist.
The compiler will substitute
it on its use besides
generating
an
appropriate code. There are
some limitations that should
be kept in mind. We
cannot
store
the declarations and
definitions of these functions in
different files. In classes,
we
have
this for certain purposes.
In case of a class, we put
the declaration of the class
and
its
basic structure in the
header file to facilitate
the users to know what
the class does
implement.
The definition of the class,
the actual code of its
functions and the
manipulations
are provided along with as object
code. Here in the template
case, the
compiler
makes a copy of the source
code and converts it to object
code. We cannot give
the
declaration of the template
function in one file and
the definition in some
other. If we
store
these in different files, it
will not compile. It does
not have real data type
and still
Page
530
CS201
Introduction to Programming
has
parameterized or generic data type in
it. So the declaration and
definition of a
template
function should be in the
same file. We will include
this file or keep
the
template
with our main program. When
it will be used, the copies
of code will be
automatically
generated. So it is a slight limitation
with templates. In any case,
template
class or
template functions are for
our own use. We do not
write template functions as
libraries
for other people as it is
like giving away our
source code.
For
template functions, we must have at least
one generic argument. There
may be more
than
one generic arguments. We
have to pass it to pieces of
data to be swapped. We
can
write
swap function as:
template<class
T>
void
swap(T &x, T &y)
{
T
tmp;
tmp =
x;
x =
y;
y =
tmp;
}
In the
above function, we are
passing both arguments of
generic type and declared a
tmp
variable of
generic type. We can also
mix generic data types
and native data types
including
user defined data types.
This template version of swap function
can be used for
integer,
double, float or char. Its
copy will be created after
writing the swap(a, b)
in
the
program.
If we have int
a, b; in the
program, int
copy
of swap
function
will be generated.
If you
have written char a, b;
a
char
copy
of swap
function
will be generated. A copy is
simple
substitution of char
with
T. Just
replace T
with
char
in
the swap
function
and
remove
the first line i.e. template<class
T>, this is
the function that the
compiler will
generate.
Now we have seen examples of
one generic and two
generic arguments
functions.
You can write template
functions with more than two
generic arguments.
So far, we
have been using only
one generic data type.
However, the things can not
be
restricted
to only one generic data
type. We can use more than
one generic data types
in
template
functions. We can do that by extending
the template<class
T>. The
use of two
generic
types can be written
as:
template
<class T, class U>
We can
use any name in place of
T
and
U. Two
data types can be mixed
here. So we can
write a
function that takes an int
and
float
and
can multiply these two. We
can use T
as
int
and
U
as
float
or
whatever is the function requirement.
Let's look at another example
of
template
function. We want to write a
function that takes two
arguments of same type
and
tells
which of the two is greater.
The code will be as
below:
// A
small program shows the use
of template function
Page
531
CS201
Introduction to Programming
#include<iostream.h>
//
template function of deciding a larger
number
template<class
T>
T larger(T x, T
y)
{
T
big;
if (x >
y)
big =
x;
else
big =
y;
return(big);
}
// the
main function
void
main()
{
int i =
7, j = 12;
double x
= 4.5, y = 1.3;
cout
<< "The larger of " << i << " and "
<< j << " is " << larger(i, j)<<
endl;
cout
<< "The larger of " << x << " and "
<< y << " is " << larger(x,
y)<< endl;
//cout <<
"The larger of " << x << "
and " << y << " is " << larger(i,
y)<< endl;
}
The
output of the program is:
The
larger of 7 and 12 is 12
The
larger of 4.5 and 1.3 is
4.5
The
function larger
is
very simple. We have two
arguments in it, compared
these two
arguments
and set the variable bigger. You
have noticed that the
definition of larger
is
not
exactly correct. In the if
condition,
we check that x
is
greater than y.
So in
the else-
part
x
can be
equal to or lesser than y. Let's
see their use in the main.
We declare two
integers
i
and
j
and
two doubles x
and
y. Then we
use the cout
to
display the result.
The
larger
function
will return the bigger
argument. When we write larger(i,
j),
the compiler
will
detect it and generate an int
version of
the larger function. In the
next line, we have
used
larger(x,
y) as
x
and
y
are
double. Here, the compiler
will generate a double
version
of the
larger
function.
Now compile the program and
it is ready to be executed. The
two
versions
of larger
functions
will be executed .We get
the larger of two integers
and larger
of two
doubles. You have noticed
that the last line of
the code is commented out.
In that
line, we
are trying to call the
larger
(i, y). There
is a problem that if you uncomment
this
line, it
will not be compiled. We
have only defined one
generic class type in
the
templatized
function i.e. class
T.
Here we are trying to call it
with an int
and a
double.
The
compiler does not know
what to do with it. Either
it should promote the int
to
double
and
call the double
version or
demote the double
into
int
and
call the int
version.
But the
Page
532
CS201
Introduction to Programming
compiler
will not make this decision.
It will be a compile time
error. We can write
another
template function that handles
two data types or try to
call this function with
one
data
type. Be careful about these
fine points. Template is a nice thing to
use but needs to
be used
carefully. The compiler may
give an error, so you have
to correctly use it. Here
in
the
larger function, we have to provide
both arguments of the same
data type.
Following
is an example of larger
function
using two different generic
types.
// A
template function example using
two generic types
#include<iostream.h>
//
template function
template
<class T, class U>
void
larger(T val1, U val2)
{
if (val1
> val2)
cout<<"First
is larger"<<endl;
else
cout<<"First
is not larger"<<endl;
}
// main
function
void
main()
{
larger(2.1,
9);
larger('G',
`A');
}
The
output of the program is:
First is
not larger
First is
larger
Overloading
Template Functions
Let's
take benefit of our knowledge
and discuss the things of
the next level i.e.
function
overloading.
Under the techniques employed in
function overloading, the functions
have
the
same name but differ
either by the number of
arguments or the type of the
arguments.
Remember
that the return type is not
a differentiator when you
are overloading the
functions.
Now if the number or type of
the arguments is different
and the function
name
is same,
the compiler will
automatically call the
correct version. The same rule
applies to
the
template function. We can
write overloaded template functions as
long as there is use
of
different number or type of
arguments.
We have
written a templatized swap
function.
Let's rename that function
as inverse.
It
will
swap the variables. We have
another inverse
function
that takes one argument
and
return
the minus of the argument
supplied. We have two template functions
named
inverse. Here is
the code of the
program:
Page
533
CS201
Introduction to Programming
// An example of
overloaded template functions.
#include<iostream.h>
//
template function
template<class
T>
void
inverse(T &x, T &y)
{
T
temp;
temp =
x;
x =
y;
y =
temp;
}
//
overloaded inverse
fucntion
template<class
T>
T
inverse(T x)
{
return
(-x);
}
// the
main fucntion
void
main()
{
int i =
3, j = 5;
//
calling the templatized
functions
inverse(i);
inverse(i,
j);
cout
<< "i = " << i << ", j = " << j <<
endl;
}
The
output of the program is:
i = 5.6,
j = -3.4
In the
above program, we have
overloaded template functions. When we
write invers(i),
the
compiler will detect the
inverse
function
with one argument and
generate its int
code.
However,
on writing inverse
(i, j), it will
generate an int
version of
the inverse
function
which
takes two parameters. This
is not a good example as the
function names are
confusing.
The function which does
swapping should be named as swap while
the one
doing
negative should be named as
negative. There might be
good occasions where
you
might
want to use overloaded
templates. The same rule of ordinary
function overloading
applies
on template function overloading.
Explicitly
Specifying the Type in a
Template Function
Page
534
CS201
Introduction to Programming
In the
template functions, sometimes we want to
see which version of the
template
function
should be used. Let's take
the example of reverse
function.
We call that function
for
double
data
type. A function for the
double
would
have been generated and
its
negative
value will be returned. Suppose we
want to pass it a double
but
return an
integer. We want
to return a negative integer
that was a part of the
double variable,
passed to
the function. We can force
the compiler to generate an
int
version of
this
function
while not passing it an int. It can
take place when we are going
to call the
function
in the program. We write the
data type in the angle
brackets between the
function
name and argument list.
For example, if we have a template reverse
function,
which
returns -x.
In the
program, we have double
a. As
soon as we write reverse(a),
the
compiler
will generate a double
version of
reverse
function.
Now we want that `a'
should
be passed
to this function while returning an
int. The
prototype of the function is T
reverse(T
x).
We want that T
should be
replaced by int. At the
same time, we want to
pass
it double. To obtain this, we
will write as reverse
<int> (a); writing
<int>
forces
the
compiler
to also generate an integer version of
the function. There may be
instances
where
this technique is useful.
Suppose,
we have a template of reverse
function
that depends on two generic
data types.
The
function template is as
follows:
template
<class T, class U>
T reverse
(U x)
{
return
-x;
}
Now
the return type is T
while
the argument is of type U. In the
body of the function, we
return
-x
and
the conversion automatically
takes place. In this
function template, we
are
using
two generic types. The
return type cannot force anything as it
is used later in the
assignment
statement. If we have double
a in
the program, and say
reverse(a);
What
version
will be generated? What will
be replaced with T
and
U? We can
force it as
reverse<int>(a);
In
that case, it will force T
to
become int. It will
force U
to
become of
the type
a
i.e.
double. It will
take a double number,
reverse and convert it into
int
and
return
it. You can explicitly
specify it as reverse<int,
double> (a); so we
have specified
both
T
and
U. We are
specifying this to the
compiler so that when the
compiler generates
the
code, it carries out it for
these versions. It is like
the default argument list.
You can
not force
the second part only i.e.
you can not force U
only
while missing T. It has
to go
left to
right. You can do as revere<double,
double> (a); or reverse(double,
int>(a).
The
appropriate
versions will be generated.
Actually, you can force what
type of versions
should be
generated in your code.
Normally, we do not need to force
the template
functions.
Normally the template
function is used for
different data types
while
generating
appropriate versions by the
compiler.
Here is
the code of the
above-explained program:
// An example of
forcing the template functions
for some specific data
type
Page
535
CS201
Introduction to Programming
#include<iostream.h>
template
<class T, class U>
T reverse
(U x)
{
return
(-x);
}
// main
function
void
main()
{
double
amount = -8.8;
//
calling the function as
double reverse(int)
cout
<< reverse<double, int>(amount) <<
endl;
//
calling the function as
double reverse(double a)
cout
<< reverse<double>(amount) <<
endl;
//
calling the function as
double reverse(double a)
cout
<< reverse<double, double>(amount) <<
endl;
//
calling the function as int
reverse(int a)
cout
<< reverse<int, int>(amount) <<
endl;
}
The
output of the code is as
follows:
8
8.8
8.8
8
Template
Functions and
Objects
We have
seen the template functions
and know that classes
also have member functions.
Can we
use these templates with
the member functions of a class? Yes, we
can templatize
member functions.
The operations used within
template functions should be present
in
the
public part of the class.
Let's see an example to understand this.
Suppose we have
created a
class PhoneCall. We have
a lengthOfCall
data
member in the class that
tells
about
the duration of the call. Another
character data member is billCode. The
billCode
will
tell us that this call is
local, domestic or international. Suppose, we browse
the bill
and
notice a wrong call. What
should we do? We will pick
up the phone and call
the
phone
company or go the phone company office to
get the bill corrected.
How will they
do that?
They will verify it with the
record and see there is no
such call or the duration
is
not
chargeable. So far, we have been
using the reverse
function
to minus the input
argument.
Here we want to reverse the
phone call. Suppose, we define
that when the
Page
536
CS201
Introduction to Programming
billCode
is
`c', it means that call
has been reversed or
cancelled. Can we use this
concept
and
write a reverse
function
for this class. Let's
revisit the reverse
function
template.
template<class
T>
T
reverse(T x)
{
return
(-x);
}
Here T
is
the generic type that
will be replaced with int,
float etc. Can we replace
T
with
the
object of the class PhoneCall. How
will that work? Let's
replace the T
with
PhoneCall, the
code looks like:
PhoneCall
reverse(PhoneCall x)
{
return
(-x);
}
The
declaration line shows that
it returns an object of PhoneCall
and
takes an argument
of type
PhoneCall. Inside
the body of the function, we
are returning -x. What
does
PhoneCall
mean?
When we are using template functions in
the classes, it is necessary
to
make
sure that whatever usage we
are implementing inside the template
function, the
class
should support it. Here we
want to write PhoneCall.
So a
minus operator should
be
defined
for the PhoneCall
class. We
know how to define operators
for classes. Here the
minus
operator for PhoneCall
will
change the billCode
to
`c' and return the object of
type
PhoneCall. Let's
have a look on the
code.
// A
simple program to show the
usage of the template functions in a
class
#include<iostream.h>
//
reverse template
function
template<class
T>
T
reverse(T x)
{
return
(-x);
}
//
definition of a class
class
PhoneCall
{
private:
int
lengthOfCall; // duration of the
call
char
billCode; // c for cancelled, d
for domestic, i for international, l for
local
Page
537
CS201
Introduction to Programming
public:
PhoneCall(const
int l, const char b); //
constructor
PhoneCall
PhoneCall::operator-(void); // overloaded
operator
int
getLengthOfCall(){ return
lengthOfCall;}
void
showCall(void);
};
PhoneCall::PhoneCall(const
int len=0, const char
b='l')
{
lengthOfCall
= len;
billCode
= b;
}
void
PhoneCall::showCall(void)
{
cout
<<"The duration of the call is "
<< lengthOfCall << endl;
cout
<<"The code of the
call is " << billCode <<
endl;
}
//
overloaded operator
PhoneCall
PhoneCall::operator-(void)
{
PhoneCall::billCode='c';
Return
(*this);
}
// main
function
void
main()
{
PhoneCall aCall(10,
'd');
aCall.showCall();
aCall =
reverse(aCall);
aCall.showCall();
}
The
output of the code
is:
The
duration of the call is 10
The
code of the call is d
The
duration of the call is 10
The
code of the call is c
We have
overloaded the minus
operator in the PhoneCall
class. We
cannot change the
unary or
binary nature of operators.
The minus operator is lucky
due to being unary as
well as
binary simultaneously. Here, we have
overloaded unary minus
operator so, it can
be
written as -x. The
definition of operators is same as
ordinary functions. We can write
whatever is
required. Here we are not
taking negative of anything but
using it in actual
meaning
that is reversing a phone
call. In the definition of
the minus operator, we
have
Page
538
CS201
Introduction to Programming
changed
the billCode
to
`c' that is cancelled and
the object of type PhoneCall
is
returned.
Now
look at the definition of
the reverse
template
function and replace the
T
with
PhoneCall. In the
body of the function where we have
written x, the
minus operator of
the
PhoneCall
class
will be called. Since it is a member
operator and the calling
object is
available to
it. Now let's look at
the main program. We take an
object of PhoneCall
as
PhoneCall
aCall(10, `d'); The
object aCall
is
initialized through the
constructor. Now we
display it as
aCall.showCall();
that
shows the length of the call
and bill code. After
this,
we say
reverse(aCall);
The
reverse function should not
be changing aCall
and
should
return an
object of type PhoneCall. It
means that aCall
= reverse(aCall); the
object
returned
is assigned to aCall. Reverse
is a template function, so the
compiler will
generate
a reverse
function
for PhoneCall. When it
will call -x, the
member minus
operator
of the class PhoneCall
will be
called. It will change the
billCode
of
that object
and
return the object. As we have
written aCall
= reverse(aCall) so the
object returned
from
reverse
having billCode
as
`c' will be assigned to aCall. Now
while displaying it
using
the aCall.showCall(), you
will see that the
billCode
has
been changed. So
reverse
works.
Recap
Let's
just recap what we just
did in this lecture. We have
defined a template
function
reverse. In the
template definition, this
function returns -x
whatever
x
is
passed to it.
After
this, we wrote a PhoneCall
class
and defined its minus
operator. Whenever we
have
to take
minus of the PhoneCall, this
operator will be called. This action is
based on the
phone
call domain and is to change
the bill code to `c'. So
the minus operator returns
an
object of type
PhoneCall
after
changing its bill code.
Now these two are
independent
exercises.
The class PhoneCall
does
not know about the
reverse
function.
It only has
defined
its minus operator. On the
other hand, the reverse
template
function has nothing
to do
with the PhoneCall
class. It
is the main program, linking
these two things. The
main
function declared an object of type PhoneCall
and
called the reverse
function
with
that
object. When we write the statement
aCall
= reverse (aCall); the
compiler
automatically
detects that we have got a
situation where reverse
template
function is
called
with the object of type PhoneCall. It
needs to generate a copy of this
template
function
that will work with
PhoneCall. When it
goes to generate that copy, it
encounters
with
return(-x). It has
to know that a minus
operator exists for that
class. If we have not
defined
the minus operator what
will happen. The compiler
may give an error that it
does
not
know what is -PhoneCall. On the
other hand, sometimes default
substitution takes
place. It
may not be what you
want to do. You have to be
careful and look at
the
implications
of using a template function
with a class and make
sure all the
operations
within
template function should be
defined explicitly for the
class so that function
should
work
correctly. Once this is
done, you realize that life
has become simpler. The
same
reverse
function
works for this class.
Now you can extend
the concept and say
how to
reverse a
car, how to reverse a phone
call, how to reverse an int
and so on. The idea
is
combining
two very powerful techniques
i.e. operator overloading and
template
mechanism
which provides for writing
the code at once. In the
normal overloading, the
facility
is that we can use the
same name again and
again. But we have to write
the code
each
time. Normally, the code is
different in these overloaded functions.
In this case, we
are
saying that we have to write
identical code i.e. to reverse something,
swap two things.
Page
539
CS201
Introduction to Programming
So the
code is same only data type
is different then we should go
and define a template
for
that function and thus,
template is used again and
again. We started with the
template
function,
used at program level. The
use of template with class was
also demonstrated.
This
combination has some rules.
This is that all the
operations that template
function is
using
should be defined in the
class. Otherwise, you will
have problems.
Page
540
Table of Contents:
|
|||||