C++ STL Standard Template Library - C++ Programming Tutorial
C++ Course / STL Basics / C++ STL Standard Template Library

C++ STL Standard Template Library

BLUF: Mastering C++ STL Standard Template Library is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: C++ STL Standard Template Library

C++ is renowned for its efficiency. Learn how C++ STL Standard Template Library enables low-level control and high-performance computing in the tutorial below.

In C++, the standard template library (STL) is a robust collection of template classes and functions that offer a wide range of data structures and algorithms. It enables programmers to leverage efficiently implemented general programming elements like resizable arrays, linked lists, stacks, queues, sets, maps, and a variety of algorithms.

Simple Example

Let's consider an example to demonstrate the Standard Template Library (STL) function in the C++ programming language.

Example

Example

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;

int main() {

    vector<int> numbers = {7, 2, 8, 1, 4};

    sort(numbers.begin(), numbers.end());  // STL sort algorithm

    cout << "Sorted numbers: ";

    for (int n : numbers)

        cout << n << " ";

        return 0;

}

Output:

Output

Sorted numbers: 1 2 4 7 8

Explanation:

In this instance, the array <int> serves as an STL container designed to hold integers. The Sort function is an STL algorithm responsible for arranging the elements within the array in a specific order. The range-based syntax employs an iterative approach to access and display elements within the array during the loop iteration.

Features of STL

Several features of STL in C++ are as follows:

  • Reusability: The code reduces repetition through the reusable components.
  • Efficiency: It includes adapted, pre-tested algorithms, and containers.
  • Generic programming: It uses templates to work with any data type.
  • Consistency: It provides uniform structure in various components, such as containers, algorithms, and recurrences.
  • Types of STL

C++ STL is mainly classified into four categories:

  • Containers
  • Algorithms
  • Iterators
  • Functors (Function Objects)

Now, we will explore each of these C++ STL data structures individually.

STL Containers

Containers are objects designed to store data of identical types. They are essential for constructing various data structures like arrays, lists, trees, and more.

The following containers offer information on all containers, along with the header file and the type of iterator linked to each:

Container Description Header file iterator
vector vector is a class that creates a dynamic array allowing insertions and deletions at the back. _PRESERVE17__ Random access
list list is the sequence containers that allow the insertions and deletions from anywhere. _PRESERVE18__ Bidirectional
deque deque is the double ended queue that allows the insertion and deletion from both the ends. _PRESERVE19__ Random access
set set is an associate container for storing unique sets. _PRESERVE20__ Bidirectional
multiset Multiset is an associate container for storing non- unique sets. _PRESERVE21__ Bidirectional
map Map is an associate container for storing unique key-value pairs, i.e. each key is associated with only one value(one to one mapping). _PRESERVE22__ Bidirectional
multimap multimap is an associate container for storing key- value pair, and each key can be associated with more than one value. _PRESERVE23__ Bidirectional
stack It follows last in first out(LIFO). _PRESERVE24__ No iterator
queue It follows first in first out(FIFO). _PRESERVE25__ No iterator
Priority-queue First element out is always the highest priority element. _PRESERVE26__ No iterator

Classification of containers :

1. Sequence Containers:

Sequence containers store elements in a linear order and also allow indexed access.

  • Vector: A dynamic array that automatically resizes.
  • Deque: A double-ended queue allows rapid insertion and deletion at both ends.
  • List: A doubly-linked list that supports rapid insertion and deletion in any situation.

C++ Sequence Containers Example:

Let's consider an example to showcase the Sequence Containers in C++.

Example

Example

#include <iostream>

#include <vector>

using namespace std; //using standard namespace

int main() {

    vector<int> v = {10, 20, 30, 40};

    v.push_back(50); // Add an element at the end

    cout << "Vector elements: "; //print output

    for (int x : v) cout << x << " ";

    return 0;

}

Output:

Output

Vector elements: 10 20 30 40 50

Explanation:

In this instance, we start by setting up a vector containing values {10, 20, 30, 40} and proceed to append 50 to the vector using the push_back method. Subsequently, all elements of the vector are displayed by employing a range-based for loop.

2. Associative Containers:

Associative containers store elements in key-based sorted order and automatically maintain this ordering. They organize data as key-value pairs and provide efficient lookup, insertion, and deletion based on the key.

  • Set: It stores unique elements in sorted order.
  • Map: It stores the Key value pairs that are unique and sorted.
  • Multiset: It is similar to the set but allows duplicate elements.
  • Multimap: It is similar to MAP, but duplicate keys are allowed .

C++ Associative Containers Example:

Let's consider an example to showcase the Associative containers in C++.

Example

Example

#include <iostream>

#include <map>

using namespace std; //using standard namespace

int main() {

    map<int, string> students;

    students[101] = "Alice";

    students[102] = "Bob";

    students[103] = "Charlie";

    for (auto& s: students)

        cout << "ID: " << s.first << ", Name: " << s.second << endl;

    return 0;

}

Output:

Output

ID: 101, Name: Alice

ID: 102, Name: Bob

ID: 103, Name: Charlie

Explanation:

In this instance, a map container is utilized to store key-value pairs in a sorted manner. The container maps student IDs (101, 102, 103) to corresponding names (Alice, Bob, Charlie). Subsequently, a range-based for loop is employed to iterate through the map and display each ID along with its respective name.

3. Unorderderd Associative Containers

These containers are the essential part of the C++ STL, which stores in inaccurate order and enables fast retrieval of elements using hash tables. Unordered associative containers do not maintain any order. Several unordered associative containers in C++ are as follows:

  • Uncontrolled Set: It stores unique elements in an unordered fashion.
  • Unordered Map: It stores key-value pairs with unique keys in no particular order.
  • Unordered Multiset: It is similar to unordered_set but enables duplicate elements.
  • Unordered Multimap: It is similar to unordered_map but enables multiple elements with the same key.

C++ Unordered Associative Containers Example:

Let's consider an example to showcase the unsorted associative containers in C++.

Example

Example

#include <iostream>

#include <unordered_map>

using namespace std; //Using Standard Namespace

int main() {

    unordered_map<string, int> fruitCount = { {"Apple", 10}, {"Banana", 20}, {"Orange", 15} };

    fruitCount["Mango"] = 5; // Insert new element

    for (auto& fruit: fruitCount)

        cout << fruit.first << ": " << fruit.second << endl;

    return 0;

}

Output:

Output

Mango: 5

Banana: 20

Apple: 10

Orange: 15

Explanation:

In this instance, we are using an unorderedmap to store key-value pairs in a random order to facilitate quick searches. The unorderedmap is initialized with fruit names as keys and their respective quantities as values. Subsequently, the key "Mango" is inserted into the map. Lastly, a range-based for loop is employed to traverse the map and display each fruit along with its quantity.

Note: Each container class contains a set of functions that can be used to manipulate the contents.

C++ Containers Example:

Let's examine an illustration to showcase containers in C++.

Example

Example

#include <iostream>

#include <vector>

#include <list>

#include <set>

#include <map>

int main() //main function

{

    std::vector<int> vec = {10, 20, 30, 40, 50};     // Vector Example

    std::cout << "Vector elements: ";

    for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it)

        std::cout << *it << " ";

    std::cout << "\n";

    std::list<int> lst = {100, 200, 300, 400}; // List Example

    std::cout << "List elements: ";

    for (std::list<int>::iterator it = lst.begin(); it != lst.end(); ++it)

        std::cout << *it << " ";

    std::cout << "\n";

    std::set<int> st = {5, 10, 15, 20};    // Set Example

    std::cout << "Set elements: ";

    for (std::set<int>::iterator it = st.begin(); it != st.end(); ++it)

        std::cout << *it << " ";

    std::cout << "\n";

    std::map<int, std::string> mp = {{1, "One"}, {2, "Two"}, {3, "Three"}};

    std::cout << "Map elements:\n";     // Map Example

    for (std::map<int, std::string>::iterator it = mp.begin(); it != mp.end(); ++it)

        std::cout << it->first << " -> " << it->second << "\n";

    return 0;

}

Output:

Output

Vector elements: 10 20 30 40 50 

List elements: 100, 200, 300, 400 

Set elements: 5 10 15 20 

Map elements:

1 -> One

2 -> Two

3 -> Three

Explanation:

This provided code snippet showcases the functionality of STL iterators as it loops through various containers such as vector, list, set, and map. Iterators enable the sequential traversal of elements, commencing from the begin function and concluding at the end function. While vectors and lists preserve the order of insertion, sets automatically sort their elements, and maps store key-value pairs in a sorted manner based on the keys.

STL Iterator:

In C++, iterators from the Standard Template Library (STL) act as similar to pointers and are employed to retrieve the specific elements within a container. These iterators progress sequentially from one element to the next, a procedure referred to as traversing through a container.

The iterator consists primarily of two functions:

  • Begin : The begin method retrieves an iterator pointing to the initial element in the vector.
  • end: The end function provides an iterator pointing just beyond the last element of a container.
  • Iterator Categories

Iterators are primarily categorized into five groups:

  1. Input iterator:

An Output iterator is an iterator that permits the program to modify the values in the container by dereferencing, but it does not allow reading those values. It is a one-way repetition, enabling only incrementation (++) and not decrementation (-). Output iterators are commonly employed in algorithms where data is written sequentially.

  1. Output iterator:

An output iterator functions similarly to an input iterator, with the key distinction that it permits the manipulation of a container's value but prohibits reading it. Essentially, it serves as a unidirectional iterator, specifically tailored for writing operations.

  1. Forward iterator:

Bidirectional iterators utilize the (++) and (--) operators to move back and forth within the container. They are capable of traversing the elements of a container in both forward and backward directions, one element at a time.

4.

A bidirectional iterator resembles a subsequent iteration, however, it offers enhanced capabilities to navigate both forwards and backwards within a container. This dual-direction traversal ability enables it to be both incremented (++) and decremented (--), enhancing its versatility compared to a forward iterator.

  1. Random Access Iterator:

Random access iterator is capable of retrieving arbitrary elements within a container. It encompasses all the functionalities of a bidirectional iterator and introduces an extra capability, namely pointer addition. This additional feature enables us to retrieve specific elements within a container by utilizing pointer addition.

Operations supported by iterators:

iterator Element access Read Write Increment operation Comparison
input -> v = *p ++ ==,!=
output *p = v ++
forward -> v = *p *p = v ++ ==,!=
Bidirectional -> v = *p *p = v ++,-- ==,!=
Random access ->,[ ] v = *p *p = v ++,--,+,-,+=,--= ==,!=,_PRESERVE28,PRESERVE29_=

C++ Iterator Example:

Let's examine an illustration to showcase iterators within the C++ STL.

Example

Example

#include <iostream>

#include <vector>

#include <list>

#include <set>

#include <iterator>

int main() {

       std::vector<int> vec = {10, 20, 30, 40};  // 1. Input Iterator (Reading only)

    std::vector<int>::iterator in_it = vec.begin();

    std::cout << "Input Iterator: " << *in_it << "\n";  // Read operation

    std::vector<int> vec_out(4);     // 2. Output Iterator (Writing only)

    std::ostream_iterator<int> out_it(std::cout, " ");

    *out_it = 100;  // Write operation

    std::cout << "(Output Iterator writes 100)\n";

    std::list<int> lst = {1, 2, 3, 4};     // 3. Forward Iterator (Read, Write, Increment)

    std::list<int>::iterator fwd_it = lst.begin();

    *fwd_it = 99;  // Write operation

    std::cout << "Forward Iterator: ";

    for (auto it = lst.begin(); it != lst.end(); ++it)

        std::cout << *it << " ";

    std::cout << "\n";

    std::set<int> st = {5, 10, 15, 20};     // 4. Bidirectional Iterator (++, --)

    std::set<int>::iterator bi_it = st.begin();

    std::advance(bi_it, 2);

    std::cout << "Bidirectional Iterator: " << *bi_it << "\n";

    --bi_it;

    std::cout << "After decrement: " << *bi_it << "\n";

    std::vector<int>::iterator rand_it = vec.begin();     // 5. Random Access Iterator (+, -, [ ])

    rand_it += 2;

    std::cout << "Random Access Iterator (+2): " << *rand_it << "\n";

    rand_it -= 1;

    std::cout << "Random Access Iterator (-1): " << *rand_it << "\n";

    std::cout << "Random Access Iterator with index: " << vec[2] << "\n";

    return 0;

}

Output:

Output

Input Iterator: 10

100 (Output Iterator writes 100)

Forward Iterator: 99 2 3 4 

Bidirectional Iterator: 15

After decrement: 10

Random Access Iterator (+2): 30

Random Access Iterator (-1): 20

Random Access Iterator with index: 30

Explanation:

This code showcases various kinds of STL iterators: input (for reading only), output (for writing only), forward (for reading, writing, and incrementing), bidirectional (enabling both ++ and -- operations), and random-access (supporting +, -, and ). It employs different STL containers such as vectors, lists, and sets to highlight the behaviors of their respective iterators.

STL Algorithms:

Algorithms are preexisting functions within the Standard Template Library (STL) that work on the items within containers to manage, modify, or examine their data.

Points to Remember:

  • Algorithms provide approx 60 algorithm functions to perform complex operations.
  • Standard algorithms allow us to work with two different types of containers at the same time.
  • Algorithms are not the member functions of a container, but they are the standalone template functions.
  • Algorithms save a lot of time and effort.
  • If we want to access the STL algorithms, we must include the <algorithm> header file in our program.
  • STL Algorithms Categories:

  • Non-mutating algorithms: Non-mutating algorithms are algorithms that do not modify the content of the container. They work on elements without changing their values or their order. These algorithms are usually used to search, comparison, count or find elements based on certain conditions. These algorithms can be used for all the container objects, and they make use of the forward iterators.
  • Mutating algorithms: Mutating algorithms are the algorithms that can be used to alter the value of a container. They can also be used to change the order of the elements in which they appear.
  • Sorting algorithms: Sorting algorithms are the modifying algorithms used to sort the elements in a container.
  • Set algorithms: Set algorithms are also known as sorted range algorithms. This algorithm is used to perform some function on a container that greatly improves the efficiency of a program.
  • Relational algorithms: Relational algorithms are the algorithms used to work on numerical data. They are mainly designed to perform mathematical operations on all the elements in a container.
  • C++ Algorithm Example:

Let's examine a sample code snippet to showcase algorithms in the C++ Standard Template Library (STL).

Example

Example

#include <iostream>

#include <vector>

#include <algorithm>

#include <numeric>  // For accumulate

#include <set>

int main() {

    std::vector<int> vec = {10, 20, 30, 40, 50};

    auto it = std::find(vec.begin(), vec.end(), 30);

    if (it != vec.end()) std::cout << "Found 30 in vector\n";

    std::reverse(vec.begin(), vec.end());

    std::cout << "Vector after reverse: ";

    for (int x : vec) std::cout << x << " ";

    std::cout << "\n";

    std::sort(vec.begin(), vec.end());

    std::cout << "Vector after sorting: ";

    for (int x : vec) std::cout << x << " ";

    std::cout << "\n";

    std::set<int> set1 = {1, 3, 5, 7}, set2 = {2, 3, 6, 7};

    std::vector<int> set_union_result(10);

    auto it2 = std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), set_union_result.begin());

    set_union_result.resize(it2 - set_union_result.begin());

    std::cout << "Set union: ";

    for (int x : set_union_result) std::cout << x << " ";

    std::cout << "\n";

    int sum = std::accumulate(vec.begin(), vec.end(), 0);

    std::cout << "Sum of vector elements: " << sum << "\n";

    return 0;

}

Output:

Output

Found 30 in vector

Vector after reverse: 50 40 30 20 10 

Vector after sorting: 10 20 30 40 50 

Set union: 1 2 3 5 6 7 

The sum of vector elements: 150

Explanation:

This code example demonstrates the usage of STL algorithms: find (nonmutating), reverse (mutating), sort (sorting), set_union (set algorithm), and accumulate (relational). These functions streamline tasks performed on data structures such as vectors and sets. The code efficiently carries out tasks like searching, altering, arranging, combining, and performing numerical computations.

STL Function Objects:

A function object, commonly referred to as a 'functor', is an object that includes at least one implementation of the operator function. This implies that by defining the operator function within a class and creating an object 'd' of that class, we can treat the object 'd' as a standard function.

Syntax:

It has the following syntax:

Example

struct MyFunctor {

    void operator()(int x) {

        std::cout << "Value: " << x << "\n";

    }

};

C++ Function Objects Example:

Let's examine an illustration to showcase Functors in C++ STL.

Example

Example

#include <iostream>

#include <vector>

#include <algorithm>

// Functor (Function Object) to multiply elements by a given factor

class MultiplyBy {

    int factor;

public:

    MultiplyBy(int f) : factor(f) {}

    int operator()(int x) const { return x * factor; } // Overloading operator()

};

int main() {

    std::vector<int> vec = {1, 2, 3, 4, 5};

    // Using functor in STL transform algorithm

    std::transform(vec.begin(), vec.end(), vec.begin(), MultiplyBy(3));

    std::cout << "Vector after multiplication by 3: ";

    for (int x : vec) std::cout << x << " ";

    std::cout << "\n";

    return 0;

}

Output:

Output

Vector after multiplication by 3: 3 6 9 12 15

Explanation:

This code snippet introduces a function object named MultiplyBy, which performs multiplication on each element by a specified factor through the operator. The transform function from the STL applies this function object to every element in a vector, enhancing efficiency in modifying them. Functors play a crucial role in enhancing algorithm flexibility by enabling tailored operations such as multiplication.

C++ STL Multiple Choice Questions:

  1. What is the primary advantage of using STL in C++?
  • The execution time becomes half its original duration when using STL in C++.
  • The implementation of STL offers reusable components whose code has undergone thorough testing.
  • The use of STL removes the necessity for pointers.
  • It provides GUI components.
  1. What happens if you try to insert duplicate elements into a set?
  • It will insert duplicates.
  • The insertion operation replaces any current element by default.
  • The duplicate insertion attempt results in no change to data storage.
  • A runtime error will occur.
  1. Which of the following is true about map containers in STL?
  • Allows duplicate keys.
  • Maintains elements in random order.
  • The system stores unique key-value combinations.
  • The data structure maintains keys without any values.
  1. What happens if you insert a duplicate element into a set?
  • Map containers allow existing elements to be replaced with new ones.
  • The data structure accepts two equivalent elements among its contents.
  • It throws a runtime error.
  • The duplicate is ignored.
  1. Which of the following statements about STL is false?
  • The STL framework enables generic programming through templates.
  • STL containers manage memory automatically.
  • STL algorithms possess the ability to modify the size of their containing elements.
  • STL delivers optimized solutions with established tests.

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience