STL Containers

STL Containers

When to use vectors, arrays, maps, sets, queues, and container adapters.

STL Containers

Sequence containers

std::vector<int> values{1, 2, 3};
values.reserve(16);

For most dynamic sequences, std::vector is the default because contiguous storage is simple, cache-friendly, and broadly compatible with algorithms.

Associative containers

Tree-based and ordered by key.

std::map<std::string, int> counts;
counts["Ada"] = 1;

Unordered containers

Hash-based with average constant-time lookup.

std::unordered_map<std::string, int> counts;
counts["Ada"] = 1;

Choose unordered containers when fast lookup matters more than sorted traversal.

Container adapters

Adapters intentionally hide some underlying-container operations so the API matches the data-structure role more closely.

Common operations

std::vector<int> values{1, 2, 3};
values.push_back(4);
values.emplace_back(5);
values.erase(values.begin());

Iteration

for (auto it = values.begin(); it != values.end(); ++it) {
    std::cout << *it << '\n';
}

Selection rules

Fast choice table

Iterator invalidation quick notes

When container choice affects references, iterators, or views held elsewhere in the program, invalidation rules often matter more than raw big-O complexity.

Common mistakes

Modern container-adjacent tools

void render(std::span<const int> pixels);
std::mdspan<float, std::extents<std::size_t, 4, 4>> matrix(view_ptr);

Practical selection hints

Common mistakes

Example in practice

#include <vector>

int main() {
    std::vector<int> values{1, 2, 3};
    values.push_back(4);
    return values.back();
}

Try this variation

Swap `std::vector` for `std::deque` or `std::unordered_map` in a toy example and note what changes in iteration, lookup, and invalidation rules.

#include <deque>

int main() {
    std::deque<int> values{1, 2, 3};
    values.push_front(0);
    return values.front();
}