Standard Template Library
Standard Template Library
Standard Template Library
Templates are a feature of the C++ programming language that allows functions and classes to
operate with generic types. This allows a function or class to work on many different data types
without being rewritten for each one.
The way we use normal parameters to pass as a value to function, in the same manner template
parameters can be used to pass type as argument to function. Basically, it tells what type of
data is being passed to the function.
Here, ‘type’ is just a placeholder used to store the data type when this function is used you can
use any other name instead class is used to specify the generic type of template, alternatively
typename can be used instead of it.
Assume we have to swap two variables of int type and two of float type. Then, we will have to
make two functions where one can swap int type variables and the other one can swap float type
variables. But here if we use a generic function, then we can simply make one function and can
swap both type of variables by passing their different type in the arguments. Let’s implement
this:
#include <iostream>
using namespace std ;
// creating a generic function ‘swap (parameter-list)’ using template :
template <class X>
void swap( X &a, X &b) {
X tp;
tp = a;
a = b;
b = tp;
cout << " Swapped elements values of a and b are " << a << " and " << b << " respectively " <<
endl;
}
int main( ) {
int a = 10, b = 20 ;
float c = 10.5, d = 20.5 ;
swap(a , b); // function swapping ‘int’ elements
swap(c , d); // function swapping ‘float’ elements
return 0;
Output :
After creating the generic function, compiler will automatically generate correct code for the
type of data used while executing the function.
C++ STL also has some containers (pre-build data structures) like vectors, iterators, pairs etc.
These are all generic class which can be used to represent collection of any data type.
Iterator
An iterator is any object that, points to some element in a range of elements (such as an array
or a container) and has the ability to iterate through those elements using a set of operators
(with at least the increment (++) and dereference (*) operators).
A pointer is a form of an iterator. A pointer can point to elements in an array, and can iterate
over them using the increment operator (++). There can be other types of iterators as well. For
each container class, we can define iterator which can be used to iterate through all the
elements of that container.
Example:
For Vector:
You will see the implementations using iterators in the topics explained below.
String
C++ provides a powerful alternative for the char*. It is not a built-in data type, but is a
container class in the Standard Template Library. String class provides different string
manipulation functions like concatenation, find, replace etc. Let us see how to construct a string
type.
string s0; // s0 = “”
string s1(“Hello”); // s1 = “Hello”
string s2 (s1); // s2 = “Hello”
string s3 (s1, 1, 2); // s3 = “el”
string s4 ("Hello World", 5); // s4 = “Hello”
string s5 (5, ‘*’); // s5 = “*****”
Implementation:
#include <iostream>
#include <cstdio>
int main()
{
string s, s1;
s = "HELLO";
s1 = "HELLO";
if(s.compare(s1) == 0)
cout << s << " is equal to " << s1 << endl;
else
cout << s << " is not equal to " << s1 << endl;
s.append(" WORLD!");
cout << s << endl;
printf("%s\n", s.c_str());
if(s.compare(s1) == 0)
cout << s << " is equal to " << s1 << endl;
else
cout << s << " is not equal to " << s1 << endl;
return 0;
}
Output:
Vector
Vectors are sequence containers that have dynamic size. In other words, vectors are dynamic
arrays. Just like arrays, vector elements are placed in contiguous storage location so they can
be accessed and traversed using iterators. To traverse the vector we need the position of the
first and last element in the vector which we can get through begin() and end() or we can use
indexing from 0 to size(). Let us see how to construct a vector.
Traverse:
void traverse(vector<int> v)
{
vector <int>::iterator it;
for(it = v.begin();it != v.end();++it)
cout << *it << ‘ ‘;
cout << endl;
for(int i = 0;i < v.size();++i)
cout << v[i] << ‘ ‘;
cout << endl;
Implementation:
#include <iostream>
#include <vector>
int main()
{
vector <int> v;
vector <int>::iterator it;
v.push_back(5);
while(v.back() > 0)
v.push_back(v.back() - 1);
for(it = v.begin(); it != v.end();++it)
cout << *it << ' ';
cout << endl;
for(int i = 0;i < v.size();++i)
cout << v.at(i) << ' ';
cout << endl;
while(!v.empty())
{
cout << v.back() << ' ';
v.pop_back();
}
cout << endl;
return 0;
Output:
543210
543210
012345
List
List is a sequence container which takes constant time in inserting and removing elements. List
in STL is implemented as Doubly Link List.
The elements from List cannot be directly accessed. For example to access element of a
particular position ,you have to iterate from a known position to that particular position.
//declaration
Implementation:
#include <iostream>
#include <list>
using namespace std;
int main()
{
list <int> LI;
list <int>::iterator it;
//inserts elements at end of list
LI.push_back(4);
LI.push_back(5);
//inserts elements at beginning of list
LI.push_front(3);
LI.push_front(5);
Output:
431
Pair
Pair is a container that can be used to bind together a two values which may be of different
types. Pair provides a way to store two heterogeneous objects as a single unit.
We can also initialize a pair using make_pair() function. make_pair(x, y) will return a pair with
first element set to x and second element set to y.
p1 = make_pair(2, ‘b’);
To access the elements we use keywords, first and second to access the first and second
element respectively.
Implementation:
#include <iostream>
#include <utility>
int main()
{
pair <int, char> p;
pair <int, char> p1(2, 'b');
p = make_pair(1, 'a');
cout << p.first << ' ' << p.second << endl;
cout << p1.first << ' ' << p1.second << endl;
return 0;
Output:
1a
2b
Sets
Sets are containers which store only unique values and permit easy look ups. The values in the
sets are stored in some specific order (like ascending or descending). Elements can only be
inserted or deleted, but cannot be modified. We can access and traverse set elements using
iterators just like vectors.
Traverse:
void traverse(set<int> s)
{
set <int>::iterator it;
for(it = s.begin();it != s.end();++it)
cout << *it << ‘ ‘;
cout << endl;
Implementation:
#include <iostream>
#include <set>
int main()
{
set <int> s;
set <int>::iterator it;
int A[] = {3, 5, 2, 1, 5, 4};
for(int i = 0;i < 6;++i)
s.insert(A[i]);
for(it = s.begin();it != s.end();++it)
cout << *it << ' ';
cout << endl;
return 0;
Output:
12345
Maps
Maps are containers which store elements by mapping their value against a particular key. It
stores the combination of key value and mapped value following a specific order. Here key value
are used to uniquely identify the elements mapped to it. The data type of key value and mapped
value can be different. Elements in map are always in sorted order by their corresponding key
and can be accessed directly by their key using bracket operator ([ ]).
In map, key and mapped value have a pair type combination,i.e both key and mapped value can be
accessed using pair type functionalities with the help of iterators.
//declaration. Here key values are of char type and mapped values(value of element) is of int
type.
mp[‘b’] = 1;
It will map value 1 with key ‘b’. We can directly access 1 by using mp[ ‘b’ ].
mp[‘a’] = 2;
Implementation:
#include <iostream>
#include <map>
using namespace std;
int main(){
map <char,int> mp;
map <char,int> mymap,mymap1;
//insert elements individually in map with the combination of key value and value of element
mp.insert(pair<char,int>('a',2)); //key is 'c' and 2 is value.
mp.insert(pair<char,int>('b',1));
mp.insert(pair<char,int>('c',43));
/* prints swapped elements of mymap and mymap1 by iterating all the elements through
using iterator. */
cout<<"Swapped elements and their keys of mymap are: "<<endl;
for(it=mymap.begin();it!=mymap.end();it++)
{
cout<<it->first<<" "<<it->second<<endl;
}
cout<<"Swapped elements and their keys of mymap1 are: "<<endl;
for(it=mymap1.begin();it!=mymap1.end();it++)
{
cout<<it->first<<" "<<it->second<<endl;
}
//erases element mapped at 'c'.
mymap1.erase('c');
return 0;
Output:
Declaration:
stack <int> s;
Implementation:
#include <iostream>
#include <stack>
//size of stack s
cout<<”Size of stack is: ” <<s.size( )<<endl;
//accessing top element from stack, it will be the last inserted element.
cout<<”Top element of stack is: ” <<s.top( ) <<endl ;
if(s.empty())
{
cout <<”Stack is empty.”<<endl;
}
else
{
cout <<”Stack is Not empty.”<<endl;
}
return 0;
Output:
Stack is empty.
Queues:
Queue is a container which follows FIFO order (First In First Out) . Here elements are
inserted at one end (rear ) and extracted from another end(front) .
Declaration:
queue <int> q;
Some member function of Queues are:
push( ): inserts an element in queue at one end(rear ). Its time complexity is O(1).
pop( ): deletes an element from another end if queue(front). Its time complexity is O(1).
front( ): access the element on the front end of queue. Its time complexity is O(1).
empty( ): checks if the queue is empty or not. Its time complexity is O(1).
size( ): returns the size of queue. Its time complexity is O(1).
Implementation:
#include <iostream>
#include <cstdio>
#include <queue>
int main() {
char qu[4] = {'a', 'b', 'c', 'd'};
queue <char> q;
int N = 3; // Number of steps
char ch;
for(int i = 0;i < 4;++i)
q.push(qu[i]);
for(int i = 0;i < N;++i) {
ch = q.front();
q.push(ch);
q.pop();
}
while(!q.empty()) {
printf("%c", q.front());
q.pop();
}
printf("\n");
return 0;
Output:
dabc
Priority Queue:
A priority queue is a container that provides constant time extraction of the largest element, at
the expense of logarithmic insertion. It is similar to the heap in which we can add element at
any time but only the maximum element can be retrieved. In a priority queue, an element with
high priority is served before an element with low priority.
Declaration:
priority_queue<int> pq;
Implementation:
#include <iostream>
#include <queue>
int main()
{
priority_queue<int> pq;
pq.push(10);
pq.push(20);
pq.push(5);
while(!pq.empty())
{
cout << pq.top() << endl;
pq.pop();
}
return 0;
}
Output:
20
10