886 STL Containers Chapter 31 Containers can be categorized like this: � Sequence containers provide access to (half-open) sequences of elements. � Associative containers provide associative lookup based on a key. In addition, the standard library provides types of objects that hold elements while not offering all of the facilities of sequence containers or associative containers: � Container adaptors provide specialized access to underlying containers. � Almost containers are sequences of elements that provide most, but not all, of the facilities of a container. The STL containers (the sequence and associative containers) are all resource handles with copy and move operations (§3.3.1). All operations on containers provide the basic guarantee (§13.2) to ensure that they interact properly with exception-based error handling. Sequence Containers vector<T,A> list<T,A> forward_list<T,A> deque<T,A> A contiguously allocated sequence of Ts; the default choice of container A doubly-linked list of T; use when you need to insert and delete elements without moving existing elements A singly-linked list of T; ideal for empty and very short sequences A double-ended queue of T; a cross between a vector and a list; slower than one or the other for most uses The A template argument is the allocator that the container uses to acquire and release memory (§13.6.1, §34.4). For example: template<typename T, typename A = allocator<T>> class vector { // ... }; is defaulted to std::allocator<T> (§34.4.1) which uses operator new() and operator delete() when it needs to acquire or release memory for its elements. These containers are defined in <vector>, <list>, and <deque>. The sequence containers are contiguously allocated (e.g., vector) or linked lists (e.g., forward_list) of elements of their value_type (T in the notation used above). A deque (pronounced ‘‘deck’’) is a mixture of linked-list and contiguous allocation. Unless you have a solid reason not to, use a vector. Note that vector provides operations for inserting and erasing (removing) elements, allowing a vector to grow and shrink as needed. For sequences of small elements, a vector can be an excellent representation for a data structure requiring list operations. When inserting and erasing elements of a vector, elements may be moved. In contrast, elements of a list or an associative container do not move when new elements are inserted or other elements are erased. A forward_list (a singly-linked list) is basically a list optimized for empty and very short lists. An empty forward_list takes up only one word. There are surprisingly many uses for lists where most are empty (and the rest are very short). A Section 31.2 Container Overview C 887 Ordered Associative Containers (§iso.23.4.2) is the type of the comparison; A is the allocator type map<K,V,C,A> multimap<K,V,C,A> set<K,C,A> multiset<K,C,A> An ordered map from K to V; a sequence of (K,V) pairs An ordered map from K to V; duplicate keys allowed An ordered set of K An ordered set of K; duplicate keys allowed These containers are usually implemented as balanced binary trees (usually red-black trees). The default ordering criterion for a key, K, is std::less<K> (§33.4). As for sequence containers, the A template argument is the allocator that the container uses to acquire and release memory (§13.6.1, §34.4). The A template argument is defaulted to std::allocator<std::pair<const K,T>> (§31.4.3) for maps and std::allocator<K> for sets. H Unordered Associative Containers (§iso.23.5.2) is the hash function type; E is the equality test; A is the allocator type unordered_map<K,V,H,E,A> unordered_multimap<K,V,H,E,A> unordered_set<K,H,E,A> unordered_multiset<K,H,E,A> An unordered map from K to V An unordered map from K to V; duplicate keys allowed An unordered set of K An unordered set of K; duplicate keys allowed These containers are implemented as hash tables with linked overflow. The default hash function type, H, for a type K is std::hash<K> (§31.4.3.2). The default for the equality function type, E, for a type K is std::equal_to<K> (§33.4); the equality function is used to decide whether two objects with the same hash code are equal. The associative containers are linked structures (trees) with nodes of their value_type (in the notation used above, pair<const K,V> for maps and K for sets). The sequence of a set, map, or multimap is ordered by its key value (K). An unordered container need not have an ordering relation for its elements (e.g., <) and uses a hash function instead (§31.2.2.1). The sequence of an unordered container does not have a guaranteed order. A multimap differs from a map in that a key value may occur many times. Container adaptors are containers providing specialized interfaces to other containers: Container Adaptors is the container type C priority_queue<T,C,Cmp> queue<T,C> stack<T,C> Priority queue of Ts; Cmp is the priority function type Queue of Ts with push() and pop() Stack of Ts with push() and pop() The default for a priority_queue’s priority function, Cmp, is std::less<T>. The default for the container type, C, is std::deque<T> for queue and std::vector<T> for stack and priority_queue. See §31.5. Some data types provide much of what is required of a standard container, but not all. We sometimes refer to those as ‘‘almost containers.’’ The most interesting of those are: