C++ Standard Template Library (STL)


Introduction

The C++ Standard Template Library (STL) is a collection of template classes and functions that provide efficient, reusable data structures and algorithms. It allows developers to manage data and perform operations on it without needing to implement these features from scratch.

The STL includes several key components:

  • Containers: Store data elements.
  • Algorithms: Perform operations on data (e.g., sorting, searching).
  • Iterators: Provide a uniform way to traverse through container elements.
  • Function Objects (Functors): Objects that can be called as functions.

Using STL can greatly reduce development time, as it provides robust, efficient, and optimized solutions for common programming tasks.


1. C++ STL Containers

Containers are data structures that store collections of objects or data elements. The STL provides several types of containers, each designed for different use cases.

Types of Containers:

  • Sequence Containers: Store elements in a linear sequence.
    • vector
    • deque
    • list
    • array
  • Associative Containers: Store elements in a way that allows fast searching.
    • set
    • map
    • multiset
    • multimap
  • Unordered Containers: Store elements based on a hash function.
    • unordered_set
    • unordered_map
    • unordered_multiset
    • unordered_multimap
  • Container Adapters: Provide alternative interfaces to existing containers.
    • stack
    • queue
    • priority_queue

Example of Using vector (Sequence Container):

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // Create a vector of integers
    vector<int> v = {1, 2, 3, 4, 5};

    // Adding elements to the vector
    v.push_back(6);
    v.push_back(7);

    // Display elements of the vector
    for (int i : v) {
        cout << i << " ";
    }
    cout << endl;

    // Accessing elements using indices
    cout << "First element: " << v[0] << endl;

    return 0;
}

Explanation:

  • The vector<int> container stores integers.
  • Elements are added using push_back() and can be accessed by index.
  • Iterating through the vector is done using a range-based for loop.

2. C++ STL Iterators

An iterator is an object that points to an element in a container. It is used to traverse through the container's elements in a way that is independent of the container's type. Iterators are similar to pointers in that they allow access to elements.

There are several types of iterators:

  • Input Iterators: Read elements in one direction.
  • Output Iterators: Write elements in one direction.
  • Forward Iterators: Can read and write elements in one direction.
  • Bidirectional Iterators: Can move both forward and backward.
  • Random Access Iterators: Allow direct access to any element in the container.

Example of Using Iterators with vector:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> v = {1, 2, 3, 4, 5};

    // Using an iterator to traverse the vector
    vector<int>::iterator it = v.begin();
    while (it != v.end()) {
        cout << *it << " ";  // Dereference the iterator to get the value
        ++it;  // Move to the next element
    }
    cout << endl;

    return 0;
}

Explanation:

  • The iterator it is initialized to the beginning of the vector.
  • We use a while loop to traverse the container until we reach the end() of the vector.
  • The *it syntax dereferences the iterator, giving access to the value.

3. C++ STL Algorithms

The STL provides a wide variety of generic algorithms that can be used with containers. These algorithms perform common operations such as searching, sorting, modifying, and manipulating container elements.

Common Algorithms:

  • sort(): Sorts elements.
  • find(): Finds an element.
  • reverse(): Reverses elements.
  • accumulate(): Computes the sum of elements.

Example of Using sort() and find():

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> v = {4, 2, 5, 1, 3};

    // Sort the vector
    sort(v.begin(), v.end());

    // Display the sorted vector
    cout << "Sorted vector: ";
    for (int i : v) {
        cout << i << " ";
    }
    cout << endl;

    // Find an element
    auto it = find(v.begin(), v.end(), 3);
    if (it != v.end()) {
        cout << "Found element: " << *it << endl;
    }

    return 0;
}

Explanation:

  • The sort() function sorts the vector in ascending order.
  • The find() function searches for the element 3 in the vector. If found, it returns an iterator to the element.

4. C++ STL Function Objects (Functors)

A function object (or functor) is an object that behaves like a function. It is an instance of a class that defines the operator() method. Functors are often used with STL algorithms to customize the behavior of the algorithm.

Example of Using a Functor with sort():

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Functor class to compare two integers
class Compare {
public:
    bool operator()(int a, int b) {
        return a > b;  // Sort in descending order
    }
};

int main() {
    vector<int> v = {4, 2, 5, 1, 3};

    // Sort using a functor
    sort(v.begin(), v.end(), Compare());

    // Display the sorted vector
    cout << "Sorted vector (descending): ";
    for (int i : v) {
        cout << i << " ";
    }
    cout << endl;

    return 0;
}

Explanation:

  • The Compare class defines the operator() method to compare two integers.
  • We pass an instance of the Compare class to the sort() algorithm to sort the vector in descending order.

5. C++ STL Container Adapters

Container adapters are special containers that provide a specific interface for interacting with other containers. The most common container adapters are:

  • stack: A container that follows the LIFO (Last In, First Out) principle.
  • queue: A container that follows the FIFO (First In, First Out) principle.
  • priority_queue: A container that allows efficient access to the largest (or smallest) element.

Example of Using stack:

#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> s;

    // Push elements onto the stack
    s.push(10);
    s.push(20);
    s.push(30);

    // Pop and display elements
    while (!s.empty()) {
        cout << s.top() << " ";  // Access top element
        s.pop();  // Remove top element
    }
    cout << endl;

    return 0;
}

Explanation:

  • The stack<int> container is used to store integers in a LIFO order.
  • Elements are added using push(), and the top element is accessed using top(). Elements are removed with pop().