# The C++ STL — vector, pair, map, set, unordered_map, stack, queue, priority_queue

Source: https://skills101.in/learn/cpp/cpp-stl-containers — Skills101 free tutorial (C++ Programming). Updated 2026-11-09.

The **Standard Template Library (STL)** gives you ready, fast data structures. Knowing them well is half of competitive programming and DSA interviews in C++.

![STL containers: vector (dynamic array), deque and list, stack and queue, set and map (sorted trees), unordered_map and unordered_set (hash tables), priority_queue (heap), with the cost of key operations](https://skills101.in/learn-img/cpp/stl-containers.svg)

## 1. vector — the default container

![A vector with capacity 4 holding 1 to 4; push_back(5) allocates capacity 8 and copies the elements over](https://skills101.in/learn-img/cpp/vector-growth.svg)

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

int main() {
    vector<int> v = {5, 3, 8};
    v.push_back(1);              // add at the end
    v.insert(v.begin(), 9);      // add at the front (slow for big vectors)
    v.pop_back();                // remove last
    cout << v.size() << " " << v.front() << " " << v.back() << " " << v[2] << "\n";
    vector<vector<int>> grid(2, vector<int>(3, 0));   // 2 x 3 filled with 0
    grid[1][2] = 7;
    cout << grid[1][2] << "\n";
    return 0;
}
```

```text
4 9 8 3
7
```

## 2. pair

```cpp
#include <iostream>
#include <utility>
#include <string>
using namespace std;

int main() {
    pair<string, int> p = {"Asha", 92};
    auto [name, marks] = p;           // structured binding (C++17)
    cout << p.first << " " << p.second << " | " << name << " " << marks << "\n";
    return 0;
}
```

```text
Asha 92 | Asha 92
```

## 3. map and set (sorted, O(log n))

```cpp
#include <iostream>
#include <map>
#include <set>
#include <string>
using namespace std;

int main() {
    map<string, int> marks;
    marks["Ravi"] = 74;
    marks["Asha"] = 92;
    marks["Neha"] = 85;
    marks["Ravi"] += 5;                       // update
    for (const auto &[name, m] : marks) cout << name << ":" << m << " ";
    cout << "\n" << marks.count("Om") << " " << marks.size() << "\n";

    set<int> s = {5, 1, 5, 3, 1};
    s.insert(4);
    for (int x : s) cout << x << " ";
    cout << "\n" << *s.begin() << " " << *s.rbegin() << "\n";
    return 0;
}
```

```text
Asha:92 Neha:85 Ravi:79
0 3
1 3 4 5
1 5
```

- `map` keeps keys **sorted**; `set` keeps **unique** sorted values.
- `marks["Om"]` would **create** "Om" with value 0 — use `count` or `find` to check without inserting.

## 4. unordered_map (hash table, O(1) average)

```cpp
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;

int main() {
    string text = "banana";
    unordered_map<char, int> freq;
    for (char c : text) freq[c]++;
    cout << freq['a'] << " " << freq['n'] << " " << freq['b'] << "\n";
    return 0;
}
```

```text
3 2 1
```

Use `unordered_map` when you don't need order — it's faster on average. Use `map` when you need sorted keys or guaranteed O(log n).

## 5. stack, queue, deque, priority_queue

```cpp
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
using namespace std;

int main() {
    stack<int> st;
    st.push(1); st.push(2); st.push(3);
    cout << st.top() << " ";          // 3 — last in, first out
    st.pop();
    cout << st.top() << "\n";

    queue<int> q;
    q.push(1); q.push(2); q.push(3);
    cout << q.front() << "\n";       // 1 — first in, first out

    priority_queue<int> maxHeap;
    for (int x : {4, 9, 2, 7}) maxHeap.push(x);
    cout << maxHeap.top() << " ";    // largest first
    priority_queue<int, vector<int>, greater<int>> minHeap;
    for (int x : {4, 9, 2, 7}) minHeap.push(x);
    cout << minHeap.top() << "\n";   // smallest first
    return 0;
}
```

```text
3 2
1
9 2
```

## Choosing a container

| Need | Use |
|---|---|
| A list you index and append to | `vector` |
| Key → value, sorted | `map` |
| Key → value, fastest | `unordered_map` |
| Unique values | `set` / `unordered_set` |
| LIFO / FIFO | `stack` / `queue` |
| Always the largest/smallest | `priority_queue` |

## Common mistakes

- Using `map[key]` to check existence (it inserts the key).
- `v.size() - 1` when `v` is empty — `size()` is unsigned, so it wraps to a huge number.
- Expecting `priority_queue` to give the smallest by default (it's a max-heap).

## Quick recap

- vector (default), pair, map/set (sorted, log n), unordered_map/set (hash, O(1) avg).
- stack (LIFO), queue (FIFO), priority_queue (max-heap; `greater<>` for min-heap).
- Check keys with `count`/`find`, not `[]`.


Practice quiz and free certificate: https://skills101.in/learn/cpp/cpp-stl-containers