Home C++ C++ Standard Template Library tutorial with code examples

C++ Standard Template Library tutorial with code examples

The C++ Standard Template Library (STL) is a powerful library that provides a variety of container classes, algorithms, and iterators to make programming more efficient and organized.

It includes several components, each with a specific purpose:

  1. Containers: Structures that store data.
  2. Algorithms: Functions that perform various operations on containers.
  3. Iterators: Objects that help traverse elements in containers.

Key Components of the C++ STL

  1. Containers: Include sequence containers (like vector, deque, list) and associative containers (set, map, etc.).
  2. Algorithms: Predefined functions that work on containers, such as sort, find, count, and reverse.
  3. Iterators: Objects that act as pointers to elements in containers, allowing traversal and manipulation.

1. Sequence Containers: vector

A vector is a dynamic array that can grow or shrink in size. It allows random access, making it efficient for accessing elements by index.

Example: Basic Operations with vector

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

int main() {
    vector<int> numbers = {1, 2, 3};

    // Adding elements
    numbers.push_back(4);
    numbers.push_back(5);

    // Accessing elements
    cout << "Elements: ";
    for (int num : numbers) {
        cout << num << " ";
    }
    cout << endl;

    // Removing the last element
    numbers.pop_back();

    cout << "After pop_back: ";
    for (int num : numbers) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

Output:

Elements: 1 2 3 4 5 
After pop_back: 1 2 3 4

2. Sequence Containers: deque

A deque (double-ended queue) allows fast insertion and deletion at both the beginning and the end.

Example: Basic Operations with deque

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

int main() {
    deque<int> d = {2, 4, 6};

    // Adding elements at both ends
    d.push_front(1);
    d.push_back(7);

    // Accessing elements
    cout << "Elements: ";
    for (int x : d) {
        cout << x << " ";
    }
    cout << endl;

    // Removing elements from both ends
    d.pop_front();
    d.pop_back();

    cout << "After pop_front and pop_back: ";
    for (int x : d) {
        cout << x << " ";
    }
    cout << endl;

    return 0;
}

Output:

Elements: 1 2 4 6 7 
After pop_front and pop_back: 2 4 6

3. Associative Containers: set

A set is a container that stores unique elements in a sorted order.

Example: Basic Operations with set

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

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

    // Adding elements
    s.insert(6);

    // Displaying elements (sorted automatically)
    cout << "Elements: ";
    for (int x : s) {
        cout << x << " ";
    }
    cout << endl;

    // Removing an element
    s.erase(4);

    cout << "After erase(4): ";
    for (int x : s) {
        cout << x << " ";
    }
    cout << endl;

    return 0;
}

Output:

Elements: 1 2 3 4 5 6 
After erase(4): 1 2 3 5 6

4. Associative Containers: map

A map is an associative container that stores key-value pairs with unique keys in sorted order.

Example: Basic Operations with map

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

int main() {
    map<string, int> age;

    // Inserting key-value pairs
    age["Alice"] = 25;
    age["Bob"] = 30;
    age["Charlie"] = 28;

    // Accessing elements
    cout << "Bob's age: " << age["Bob"] << endl;

    // Iterating through map
    cout << "All ages:" << endl;
    for (const auto& pair : age) {
        cout << pair.first << " is " << pair.second << " years old." << endl;
    }

    return 0;
}

Output:

Bob's age: 30
All ages:
Alice is 25 years old.
Bob is 30 years old.
Charlie is 28 years old.

5. Container Adaptors: stack

A stack is a container adaptor that allows access to elements in a Last-In-First-Out (LIFO) manner.

Example: Basic Operations with stack

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

int main() {
    stack<int> s;

    // Pushing elements onto the stack
    s.push(1);
    s.push(2);
    s.push(3);

    cout << "Top element: " << s.top() << endl;

    // Popping elements from the stack
    s.pop();
    cout << "After pop, top element: " << s.top() << endl;

    return 0;
}

Output:

Top element: 3
After pop, top element: 2

6. Container Adaptors: queue

A queue is a container adaptor that operates in a First-In-First-Out (FIFO) manner.

Example: Basic Operations with queue

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

int main() {
    queue<int> q;

    // Adding elements to the queue
    q.push(1);
    q.push(2);
    q.push(3);

    cout << "Front element: " << q.front() << endl;

    // Removing elements from the queue
    q.pop();
    cout << "After pop, front element: " << q.front() << endl;

    return 0;
}

Output:

Front element: 1
After pop, front element: 2

7. Algorithms: sort

The sort algorithm sorts elements in a range in ascending order by default.

Example: Sorting a Vector

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

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

    // Sorting in ascending order
    sort(numbers.begin(), numbers.end());

    cout << "Sorted numbers: ";
    for (int num : numbers) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

Output:

Sorted numbers: 1 2 3 4 5

8. Algorithms: find

The find algorithm searches for an element in a range and returns an iterator to the first occurrence.

Example: Finding an Element in a Vector

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

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

    // Searching for 3
    auto it = find(numbers.begin(), numbers.end(), 3);

    if (it != numbers.end()) {
        cout << "Found 3 at position " << distance(numbers.begin(), it) << endl;
    } else {
        cout << "3 not found" << endl;
    }

    return 0;
}

Output:

Found 3 at position 2

9. Iterators: Traversing Containers

Iterators are used to traverse elements in containers. They provide flexibility for accessing elements in a container without exposing the internal structure.

Example: Using Iterators with vector

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

int main() {
    vector<int> numbers = {10, 20, 30, 40, 50};

    cout << "Elements: ";
    for (vector<int>::iterator it = numbers.begin(); it != numbers.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

Output:

Elements: 10 20 30 40 50

10. Using Reverse Iterators

Reverse iterators allow traversing containers in reverse order.

Example: Using Reverse Iterators with vector

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

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

    cout << "Elements in reverse order: ";
    for (auto it = numbers.rbegin(); it != numbers.rend(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

Output:

Elements in reverse order: 5 4 3 2 1

Summary Table

Component Example Description
vector vector<int> v = {1, 2, 3}; Dynamic array with random access
deque deque<int> d = {1, 2, 3}; Double-ended queue, fast insert/delete at ends
set set<int> s = {1, 2, 3}; Stores unique, sorted elements
map map<string, int> m; m[“key”] = value; Key-value pairs, unique keys
stack stack<int> s; s.push(1); LIFO container adaptor
queue queue<int> q; q.push(1); FIFO container adaptor
sort sort(v.begin(), v.end()); Sorts elements in a range
find find(v.begin(), v.end(), 3); Finds first occurrence of an element
Iterator for (auto it = v.begin(); it != v.end(); ++it) Traverses container using an iterator
Reverse Iterator for (auto it = v.rbegin(); it != v.rend(); ++it) Traverses contain

Complete Example

This example demonstrates the use of vector, map, sort, and iterators.

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

int main() {
vector<int> numbers = {5, 3, 9, 1, 4};
map<string, int> ages = {{"Alice", 25}, {"Bob", 30}, {"Carol", 22}};

// Sorting numbers
sort(numbers.begin(), numbers.end());

cout << "Sorted numbers: ";
for (int num : numbers) {
cout << num << " ";
}
cout << endl;

// Displaying map using iterator
cout << "Ages:" << endl;
for (auto it = ages.begin(); it != ages.end(); ++it) {
cout << it->first << ": " << it->second << " years old" << endl;
}

return 0;
}

Sample Output:

Sorted numbers: 1 3 4 5 9
Ages:
Alice: 25 years old
Bob: 30 years old
Carol: 22 years old

Key Takeaways

  • Containers: Provide various data structures for organizing data.
  • Algorithms: Provide powerful functions for searching, sorting, counting, and more.
  • Iterators: Allow efficient and flexible traversal of containers.

You may also like