STL consist of three components:
- Container for storing information
- Iterators for accessing the information stored
- Algorithms for manipulating the content of the containers
STL Containers
Containers are STL classes that are used to store data. There are two types of container classes:
- Sequential containers. As the name suggests, these are containers used to hold data in a sequential fashion, such as arrays and lists. They are characterized by a fast insertion time, but are relatively slow in find operations. Such as std::vector, std::deque, std::list.
- Associative containers. Associative containers are those that store data in a sorted fashion ---- akin to a dictionary. This results in slower insertion times, but presents significant advantages when it comes to searching. Such as std::set, std::map, std::multiset, std::multimap.
STL Iterators
The simplest example of an iterator is a pointer. Given a pointer to the first element in an array, you can increment it and point to the next element or, in many cases, manipulate the element at that location.
Iterators in STL are template classes in some ways are generalization of pointers. These are template classes that give the programmer a handle by which he can work with and manipulate STL containers and perform operations on them.
Iterators supplied by STL can be broadly classified into following:
- Input iterator ---- One that can be dereferenced to reference an object. The object can be in a collection, for instance. Input iterators of the purest kinds guarantee read only access.
- Out iterator ------ One that allows the programmer to write to the collection, Output iterators of the strictest types guarantee write access only.
STL Algorithms
Finding, sorting, reversing, and the like are standard programming requirements that should not require the programmer to reinvent implementation to support. This is precisely why STL supplies these functions in the form of STL algorithms that work well with containers using iterators to help programmer with some of the most common requirements.
Some of the most used STL algorithms are
- std::find ---- Helps find a value in a collection
- std::find_if ---- Helps find a value in a collection on the basis of a specific user-defined predicate
- std::reverse ---- Reverses a collection
- std::remove_if ---- Helps remove an item from a collection on the basis of a user-defined predicate
- std::transform ---- Helps apply a user-defined transformation function to elements in a container
The Interaction Between Containers and Algorithms Using Iterators
Let's examine how iterators seamlessly connect containers and the STL algorithms using a example.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main ()
{
// A dynamic array of integers
vector <int> vecIntegerArray;
// Insert sample integers into the array
vecIntegerArray.push_back (50);
vecIntegerArray.push_back (2991);
vecIntegerArray.push_back (23);
vecIntegerArray.push_back (9999);
cout << “The contents of the vector are: “ << endl;
// Walk the vector and read values using an iterator
vector <int>::iterator iArrayWalker = vecIntegerArray.begin ();
while (iArrayWalker != vecIntegerArray.end ())
{
// Write the value to the screen
cout << *iArrayWalker << endl;
// Increment the iterator to access the next element
++ iArrayWalker;
}
// Find an element (say 2991) in the array using the ‘find’ algorithm...
vector <int>::iterator iElement = find (vecIntegerArray.begin (),vecIntegerArray.end (), 2991);
// Check if value was found
if (iElement != vecIntegerArray.end ())
{
// Value was found... Determine position in the array:
int nPosition = distance (vecIntegerArray.begin (), iElement);
cout << “Value “<< *iElement;
cout << “ found in the vector at position: “ << nPosition << endl;
}
return 0;
}