C++ Standard Template Library (STL)
The Standard Template Library (STL) is the set of C++ template classes to provide common programming data structures and functions such as vector, list, queue, map etc.
These are the core components of STL −
- Containers are used to deal with collections of objects of a certain type. There are different types of containers such as vector, list, queue, map etc.
- Algorithms act on containers. We can use them to perform initialization, sorting, searching, and transforming of the contents of containers.
- Iterators are used to iterate through the elements of collections of objects.
Example 1: vector container
Let us develop a program that demonstrates the vector container (a standard template of C++ defined in the <vector> header) which is similar to an array with an exception that it automatically handles its own storage requirements while it grows.
Iterators in C++ (defined in <iterator> header) are pointer-like entities used to access the individual elements in a container. They are moved sequentially from one element to another element. This technique is known as iterating through a container. See the program code below.
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
int main() {
vector<int> v1;
vector<int>::iterator itr;
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);
cout << "vector1 elements: " << endl;
for(itr=v1.begin(); itr!=v1.end(); itr++) {
std::cout << *itr <<" ";
}
// input array
float num[] = {11.1, 22.2, 33.3, 44.4, 55.5};
int n = sizeof(num) / sizeof(num[0]);
vector<float> v2(num, num+n);
cout << "\n\nvector2 elements: " << endl;
for(int i=0; i<v2.size(); i++) {
cout << v2.at(i) << " ";
}
return 0;
}
Output:
vector1 elements:
10 20 30 40 50
vector2 elements:
11.1 22.2 33.3 44.4 55.5
Here are following points to be noted related to various functions we used in the above example −
The push_back( ) member function inserts dat at the end of the vector, expanding its size as required.
The size( ) function displays the size of the vector.
The function begin( ) returns an iterator to the start of the vector.
The function end( ) returns an iterator to the end of the vector.
Example 2: list container
Check the following program to demonstrate the working of list container (defined in <list> header). The concept is quite similar to that of vector container.
#include <iostream>
#include <list>
#include <iterator>
using namespace std;
int main() {
// input array
int num[] = {33, 22, 11, 55, 44};
int n = sizeof(num) / sizeof(num[0]);
list<int> li(num, num+n);
list<int>::iterator itr;
cout << "list elements: " << endl;
for(itr=li.begin(); itr!=li.end(); itr++) {
std::cout << *itr <<" ";
}
li.sort(); //sort the elements of list
cout << "\n\nlist elements: " << endl;
for(itr=li.begin(); itr!=li.end(); itr++) {
std::cout << *itr <<" ";
}
return 0;
}
Output:
list elements:
33 22 11 55 44
list elements:
11 22 33 44 55
Example 3: queue container
The queue is a data structure works on the FIFO technique, where FIFO stands for First In First Out. The first element to be inserted into the queue will always be the first element to be removed.
There is an element called as ‘front’ which is the element at the first position, also there is an element called as ‘rear’ which is the element at the last position.
In normal queues, insertion of elements take place at the rear end while the deletion is done from the front end.
See the program below to illustrate the concept of queue container (defined in <queue> header).
#include <iostream>
#include <queue>
using namespace std;
void disp(queue<int> li) {
queue<int> qq = li;
cout << "[F]"; // queue front is indicated by [F]
while (!qq.empty()) {
cout << "->" << qq.front() ;
qq.pop();
}
cout << "->[R]\n"; // queue rear is indicated by [R]
}
int main() {
queue<int> fifo;
fifo.push(10);
fifo.push(20);
fifo.push(30);
fifo.push(40);
fifo.push(50);
fifo.push(60);
cout << "The queue fifo is : ";
disp(fifo);
cout << "fifo.size() : " << fifo.size() << endl;
cout << "fifo.front() : " << fifo.front() << endl;
cout << "fifo.back() : " << fifo.back() << endl;
cout << "fifo.pop() : ";
fifo.pop();
disp(fifo);
return 0;
}
Output:
The queue fifo is : [F]->10->20->30->40->50->60->[R]
fifo.size() : 6
fifo.front() : 10
fifo.back() : 60
fifo.pop() : [F]->20->30->40->50->60->[R]
Example 4: map container
Let us create a program to implement the concept of map container (defined in <map> header). Maps are containers that store elements in the form of key-value pairs. No two mapped values can have same keys.
#include <iostream>
#include <map>
#include <iterator>
using namespace std;
int main() {
map<int, string> student;
// element assignment using array index notation
student[101] = "Ram";
student[102] = "Shyam";
student[103] = "Jadu";
student[104] = "Madhu";
student[105] = "Amal";
cout << "student[105] = " << student[105] << endl << endl;
cout << "Map size: " << student.size() << endl;
cout << endl << "Normal Order:" << endl;
for(map<int,string>::iterator it=student.begin(); it!=student.end(); ++it) {
cout << (*it).first << ": " << (*it).second << endl;
}
cout << endl << "Reverse Order:" << endl;
for(map<int,string>::reverse_iterator it=student.rbegin(); it!=student.rend(); ++it) {
cout << (*it).first << ": " << (*it).second << endl;
}
return 0;
}
Output:
student[105] = Amal
Map size: 5
Normal Order:
101: Ram
102: Shyam
103: Jadu
104: Madhu
105: Amal
Reverse Order:
105: Amal
104: Madhu
103: Jadu
102: Shyam
101: Ram