The standard library containers fall into three families. Sequence containers preserve insertion order and include vector, deque, list, array, and forward_list. Associative containers store ordered keys, typically in a balanced binary search tree, and include set, map, multiset, and multimap. Unordered associative containers store keys in a hash table for average constant-time lookup and include unordered_set, unordered_map, unordered_multiset, and unordered_multimap. Choosing between them is guided by access patterns: std::vector offers constant-time random access and amortized constant-time push_back in a contiguous block, making it the default sequence container; std::deque supports constant-time insertion and removal at both ends without requiring a single contiguous block; and std::list is a doubly-linked list that offers constant-time insertion and deletion given an iterator but no random access and higher per-element memory overhead due to its pointers.
For key-value data, std::map stores pairs in a red-black tree with unique sorted keys and logarithmic-time lookup, while std::unordered_map stores them in a hash table with average constant-time lookup at the cost of requiring a hash function and losing key ordering. std::set is the value-only counterpart to std::map, holding unique sorted elements with logarithmic-time operations. std::array differs from std::vector by having a fixed compile-time size stored on the stack, which makes it preferable for small constant-size collections where no growth is needed. std::pair holds two values accessed through .first and .second, and std::tuple generalizes this to any number of values accessed through std::get<I>. std::initializer_list represents a brace-enclosed list passed to a function or constructor, which is what makes std::vector<int> v{1, 2, 3} work, and the broader brace initialization syntax, often called uniform initialization, prevents narrowing conversions at compile time, making int y{3.14} a hard error.
Iterators are generalized pointers that provide a uniform way to traverse containers. The categories input, output, forward, bidirectional, and random access describe what operations an iterator supports. begin() returns a mutable iterator that allows modifying elements, while cbegin() returns a const_iterator with read-only access. Reverse iterators obtained via rbegin() and rend() traverse a container from end to beginning. The range-based for loop for (const auto& elem : vec) works with anything that exposes begin() and end(), and the ampersand avoids copies. The <algorithm> header provides a rich set of generic functions operating on iterator pairs, including std::sort, std::find, std::count_if, std::transform, std::accumulate, and std::for_each. The auto keyword lets the compiler deduce types from initializers, dramatically reducing verbosity for iterators, lambdas, and complex template expressions.