Lab 08 - New
Lab 08 - New
Templates
Template is a new concept in C++ which enables us to define generic functions and classes
and thus provide supports for generic programming. A template can be used to create a
family of functions or classes. For example we can use the same function or class for
performing different type of data processing. Templates are sometimes called parameterized
classes or functions.
Function templates
Function templates are special functions that can operate with generic types. This allows us
to create a function template whose functionality can be adapted to more than one type or
class without repeating the entire code for each type.
In C++ this can be achieved using template parameters. A template parameter is a special
kind of parameter that can be used to pass a type as argument: just like regular function
parameters can be used to pass values to a function, template parameters allow to pass
also types to a function. These function templates can use these parameters as if they were
any other regular type.
The format for declaring function templates with type parameters is:
The only difference between both prototypes is the use of either the keyword class or the
keyword typename. Its use is indistinct, since both expressions have exactly the same
meaning and behave exactly the same way.
For example, to create a template function that returns the greater one of two objects we
could use:
template <class myType>
myType GetMax (myType a, myType b) {
return (a>b?a:b);
}
Here we have created a template function with myType as its template parameter. This
template parameter represents a type that has not yet been specified, but that can be used
in the template function as if it were a regular type. As you can see, the function
template GetMax returns the greater of two parameters of this still-undefined type.
To use this function template we use the following format for the function call:
For example, to call GetMax to compare two integer values of type int we can write:
int x,y;
GetMax <int> (x,y);
When the compiler encounters this call to a template function, it uses the template to
automatically generate a function replacing each appearance of myType by the type passed
as the actual template parameter (int in this case) and then calls it. This process is
automatically performed by the compiler and is invisible to the programmer.
int main () {
int i=5, j=6, k;
double l=10.5, m=5.6, n;
k=GetMax<int>(i,j);
n=GetMax<double>(l,m);
cout << k << endl;
cout << n << endl;
return 0;
}
In this case, we have used T as the template parameter name instead of myType because it
is shorter and in fact is a very common template parameter name. But you can use any
identifier you like.
In the example above we used the function template GetMax() twice. The first time with
arguments of type int and the second one with arguments of type double. The compiler has
instantiated and then called each time the appropriate version of the function.
As you can see, the type T is used within the GetMax() template function even to declare
new objects of that type:
T result;
Therefore, result will be an object of the same type as the parameters a and b when the
function template is instantiated with a specific type.
In this specific case where the generic type T is used as a parameter for GetMax the
compiler can find out automatically which data type has to instantiate without having to
explicitly specify it within angle brackets (like we have done before
specifying <int> and <double>). So we could have written instead:
int i,j;
GetMax (i,j);
Since both i and j are of type int, and the compiler can automatically find out that the
template parameter can only be int. This implicit method produces exactly the same result:
int main () {
int i=5, j=6, k;
double l=10.5, m=5.6, n;
k=GetMax(i,j);
n=GetMax(l,m);
cout << k << endl;
cout << n << endl;
return 0;
}
Notice how in this case, we called our function template GetMax() without explicitly
specifying the type between angle-brackets <>. The compiler automatically determines what
type is needed on each call.
Because our template function includes only one template parameter (class T) and the
function template itself accepts two parameters, both of this T type, we cannot call our
function template with two objects of different types as arguments:
int i;
double l;
k = GetMax (i,l);
This would not be correct, since our GetMax function template expects two arguments of the
same type, and in this call to it we use objects of two different types.
We can also define function templates that accept more than one type parameter, simply by
specifying more template parameters between the angle brackets. For example:
In this case, our function template GetMin() accepts two parameters of different types and
returns an object of the same type as the first parameter (T) that is passed. For example,
after that declaration we could call GetMin()with:
int i,j;
double l;
i = GetMin<int,double> (j,l);
or simply:
i = GetMin (j,l);
even though j and l have different types, since the compiler can determine the appropriate
instantiation anyway.
Class templates
We also have the possibility to write class templates, so that a class can have members that
use template parameters as types. For example:
The class that we have just defined serves to store two elements of any valid type. For
example, if we wanted to declare an object of this class to store two integer values of
type int with the values 115 and 36 we would write:
mypair<int> myobject (115, 36);
this same class would also be used to create an object to store any other type:
mypair<double> myfloats (3.0, 2.18);
The only member function in the previous class template has been defined inline within the
class declaration itself. In case that we define a function member outside the declaration of
the class template, we must always precede that definition with the template <...> prefix:
int main () {
mypair <int> myobject (100, 75);
cout << myobject.getmax();
return 0;
}
Confused by so many T's? There are three T's in this declaration: The first one is the
template parameter. The second T refers to the type returned by the function. And the
third T (the one between angle brackets) is also a requirement: It specifies that this
function's template parameter is also the class template parameter.
The Standard Template Library is a collection of classes that provide templated containers,
algorithms, and iterators. If you need a common class or algorithm, odds are the STL has it.
The upside is that you can take advantage of these classes without having to write and
debug the classes yourself, and the STL does a good job providing reasonably efficient
versions of these classes. The downside is that the STL is complex, and can be a little
intimidating since everything is templated.
Fortunately, you can bite off the STL in tiny pieces, using only what you need from it,
and ignore the rest until you’re ready to tackle it.
In the next few lessons, we’ll take a high-level look at the types of containers, algorithms,
and iterators that the STL provides. These STL components are part of C++ Library are
defined in the namespace std.
STL containers
By far the most commonly used functionality of the STL library are the STL container
classes. The STL contains many different container classes that can be used in different
situations.
Generally speaking, the container classes fall into three basic categories: Sequence
containers, Associative containers, and Container adapters. We’ll just do a quick
overview of the containers here.
Sequence containers:
Associative containers
Container adaptors
stack: Adapts a container to provide stack (LIFO data structure) (class template).
queue: Adapts a container to provide queue (FIFO data structure) (class template).
priority_queue: Adapts a container to provide priority queue (class template).
Sequence Containers
Sequence contains are container classes that maintain the ordering of elements in the
container. A defining characteristic of sequence containers is that you can choose where to
insert your element by position. The most common example of a sequence container is the
array: if you insert four elements into an array, the elements will be in the exact order you
inserted them.
The named vector class in the STL is a dynamic array capable of growing as needed to
contain its elements. The vector class allows random access to its elements via operator [ ],
and inserting and removing elements from the end of the vector is generally fast.
The following program inserts 6 numbers into a vector and uses the overloaded [] operator to
access them in order to print them.
#include <vector>
#include <iostream>
int main()
{
using namespace std;
2D Vector:
deque
The deque class (pronounced “deck”) is a double-ended queue class. It is Functionality
similar to vectors but with efficient insertion and deletion of elements also at the beginning of
the sequence, and not only at its end.
#include <iostream>
#include <deque>
int main()
{
using namespace std;
deque<int> deq;
for (int nCount=0; nCount < 3; nCount++)
{
deq.push_back(nCount); // insert at end of array
deq.push_front(10 - nCount); // insert at front of array
}
Stack Operations
s.push(8);
s.push(5);
s.push(6);
Queue Operations
q.push(8);
q.push(5);
q.push(6);
Priority queue
while( !q.empty() ) {
cout << q.top() << endl; // printing the top
q.pop(); // removing that one
}
Map
#include<iostream> Output:
#include<map> Allen 95
using namespace std; Edward 87
int main() Louise 66
{ 95
map<string,int> Mark;
Mark["Allen"] = 95;
Mark["Edward"] = 87;
Mark["Louise"] = 66;
References: https://cs.smu.ca/~porter/csc/ref/stl/index_containers.html
2. http://www.cplusplus.com/ /reference/stl/
3. https://www.geeksforgeeks.org/cpp-stl-tutorial/
4. http://www.learncpp.com
5. http://www.tutorialspoint.com/cplusplus/