Three sequential containers: vector, list, deque
Difference: How elements are accessed and the cost of operations related to adding or deleting elements.
vector: Supports fast random access (i.e. arbitrary access, distinguished from disk, tape, etc. which requires seek and rewind access)
list:Supports fast insert/delete
deque: double-ended queue
Adapter: Adapts to the underlying container type by defining a new operation interface based on the operations provided by the original container type.
Sequential container adapters: stack, queue, priority_queue
2. Built-in Types, Composite Types, and Class Types
Built-in types: Basic types built into the compiler, such as int, char, float, double, bool, etc.
Composite types: According to the types defined by other types, there are mainly several types: array, string (C-style), pointer, reference, struct, union;
Class type: Classes defined with struct and class.
Constructors that accept container size as a parameter only apply to sequential containers, which are not supported by associated containers
// Container type name c, element type T, empty container c C<T> c; // To create a copy of container c2 c,c and c2 must have the same container type and element type C c(c2); vector<int> ivec2(ivec); // c Container elements are copies of the range indicated by iterators b and e, left closed and open C c(b, e); // n elements with a value of t create a container C whose type must be the value of the element type of container C C c(n, t); // Create container c with n value initialization elements C c(n);
- Type constraints for elements in containers
- The container element type must satisfy the following two constraints:
Element types must support assignment operations, and objects of element types must be replicable.
- All built-in and composite types, except reference types, can be used as element types because references do not support assignment in the general sense.
- All standard library types except IO library types (and auto_ptr types) are valid container element types because they do not support copy and assignment.
- Containers of containers
// Yes vector<vector<string> > lines; // Error, two angle brackets must be separated by a space in the middle, otherwise they will be considered right shift operators vector<vector<string> > lines;
- list does not support arithmetic and relational operations
// list is a two-way chain table structure that does not support arithmetic operations (addition or subtraction) or relational operations (<=, <, >=, >). It only supports pre- and post-addition, self-subtraction, and equal (unequal) operations. The iterators of vector s and deque containers support list<int> ilist(vec.begin(), vec.end()); ilist.begin() + ilist.size()/2; //Wrong
- Operation of adding elements to sequential containers
c.push_bach(t); // Add an element with a value of t to the front of c, returning the void type. Only applies to list s and deques, not vectors c.push_front(t); // Add an element with a value of t before the element that iterator p points to, returning an iterator that points to the newly added element c.insert(p,t); // Add n elements with a value of t in front of the element pointed to by iterator p to return the void type c.insert(p,n,t); // Add elements within the range marked by iterators b and e before the elements pointed to by iterator p, returning void c.insert(p,b,e);
- Container Size Operation
// The resize operation may invalidate the iterator, and if the resize operation compresses the container, the iterator pointing to the deleted element will fail. c.size(); c.empty(); // Returns the maximum number of elements that a container C can hold, and the return type is c::size_type c.max_size(); //Adjust the size of the container to n. If n<c.size(), delete the extra elements. Otherwise, add a new element initialized by the value c.resize(n); // Adjust the size of the container to n, and all newly added elements have a value of t c.resize(n,t);
- Access Elements
// Returns a reference to the last element of container c c.back(); // Returns a reference to the first element of container c c.front(); // Returns a reference to an element marked n, if n<0 or n>=c.size(), the operation is undefined and error occurs c[n]; // Returns a reference to an element marked n, if n<0 or n>=c.size(), the operation is undefined, throwing an out_of_range exception c.at(n);
- Delete element
// Deletes the element pointed at by iterator p, returns the element after the deleted element, returns the next position of the last element if P points to the last element, and undefined if P points to the next position of the last element c.erase(p); // Deletes all elements within the range marked by iterators b and E (excluding those pointed to by e), returns an iterator pointing to the element after the deleted element segment, and returns an iterator pointing to the next location of the last element if e points to the next location of the last element c.erase(b,e); // Remove all elements from the container and return void c.clear(); // Deletes the last element of the container, returns void, and if c is not empty, the function is undefined c.pop_back(); // Delete the first element of the container and return void. If C is not an empty container, the function is undefined and only applies to list and deque Containers (both based on a chain table). Deletion is not a strong feature of vector s. Deletion is random access. If the first element is deleted, the subscript-1 of all subsequent elements, c programming c, is too cumbersome for random access. c.pop_front(); //The erase, pop_front, and pop_bach functions invalidate all iterators pointing to deleted elements, and for vector containers, iterators pointing to elements following the deletion point usually fail, while for dequecontainers, if the first or last element is not included in the deletion, all iterators associated with the dequecontainer will fail.
Assignment and swap
If the element types are different but compatible in containers of different (or the same) types, the assignment operation must use the assign function instead of the copy operator=, or if both the container type and the element type in the container are the same, the copy operator=.
// Delete all elements from container C1 and copy elements from c2 to c1. Container types and container element types of C1 and c2 must be the same c1 = c2; // Container C1 stores the elements of container c2. Container C2 stores the elements of original container c1. This function executes faster (constant time) than replication. The iterator will not fail, and the original iterator still points to the original element. c1.swap(c2); // Reset the elements of c, copy all elements within the scope of iterator B and e tags to c, B and e must not b e iterators pointing to elements in c, left operand iterators fail. c.assign(b,e); // The left operand iterator fails by resetting container c to store n elements with a value of t. c.assign(n,t);
- Self-growth of vector s container
- To support fast random access, vector s store elements in containers in a continuous manner, where each element is stored next to the previous element.
- When an element is added to a container, if there is no room for new elements in the container, the vector s must reallocate the storage space to store the original elements and add new elements. Elements stored in the old storage space are copied into the new storage space, new elements are inserted, and the old storage space is finally revoked.
- In order for vector s to achieve fast memory allocation, they actually allocate more space than they currently need
capacity and reserve members
The capacity operation gets the total number of elements that can be stored before the container needs to allocate more storage space. The size is the number of elements the container currently has.
The reserve operation tells the vector container how many elements should be reserved for storage.
ivec.reserve(50); // 50 ivec.capacity();
- Selection of Containers
- Vectors and deque Containers provide quick random access to elements at the expense of inserting or deleting elements anywhere in the container (shifting is required), which is more expensive than inserting and deleting them at the end of the container.
- list types can be inserted and deleted quickly anywhere at the expense of random access to elements.
- A dequeue two-way queue is a continuous linear space with two-way openings that efficiently inserts and deletes elements at both ends of the head and tail, and dequeues are very similar to vector s on the interface.
- Like vector s, insert and erase elements are less efficient in deque containers
- Unlike vectors, dequeContainers provide efficient insert and erase operations at the top, just like at the end of a container
- Like vector s and unlike list s, deque s support random access to all elements
- Inserting elements at the beginning and end of a dequeContainer does not invalidate any iterators. Deleting elements at the beginning or end invalidates only those iterators that point to deleted elements. Inserting and deleting elements anywhere else in the dequeContainer invalidates all iterators that point to the container elements.
- Methods for constructing string objects
// Create a string object that is initialized as a copy of the first n elements of the array pointed to by cp string s(cp, n) // Create a string object that is initialized as a copy of the character starting with the subscript pos2 in an existing string object s2. If pos2 > s2.size(), the operation is undefined string s(s2, pos2) // Create a string object that is initialized as a copy of len2 characters from the subscript pos2 in an existing string object s2. If pos2 > s2.size(), the operation is undefined string s(s2, pos2, len2); string s1; // "aaaaa", note the difference from string s(s2, pos2) string s2(5, 'a'); string s3(s2); // "aa" string s4(s3.begin(), s3.begin() + s3.size() / 2);
- Several operations of string type different from container type
// insert, assign, erase, and other operations are basically the same as vector s and other containers // Returns a string of n characters starting at pos position from string s s.substr(pos,n); // Returns a string from pos position to end position in string s s.substr(pos); // Return a copy of s s.substr(); s.append(args); // Delete the len character from pos position in s, replace it with the character specified by args, return the reference of s, args cannot be b2,e2 s.replace(pos,len,args); // Deletes all characters in iterator b to e, replaces them with args, returns a reference to s, args cannot b e s2,pos2,len2 s.replace(b,e,args) //args for operation: s2 // String s2 s2, pos2, len2 // len2 characters from subscript pos2 in string s2 cp // Array terminated with empty character pointed to by pointer cp cp, len2 // The first two len characters in an array ending with a null character pointed to by pointer cp n, c // The first n copies of character c b2, e2 // All characters in the range of iterator b2 and e2 Tags // Find the first occurrence of args in s s.find(args); // Find the last occurrence of args in s s.rfind(args); // Find the first occurrence of any character in args in s s.find_first_of(args); // Find the last occurrence of any character in args in s s.find_last_of(args); // Find the first character in s that does not belong to args s.find_first_not_of(args); // Find the last character in s that does not belong to args s.find_last_not_of(args); //args for operation: c, pos //In s, start with the subscript pos to find the character c,pos defaults to 0 s2, pos // In s, start with the subscript pos to find the string object s2,pos defaults to 0 cp, pos // In s, start with the subscript pos to find the C-style string that the pointer cp points to, ending with a null character. The default value of pos is 0 cp, pos, n // In s, start with the subscript pos to find the first n characters of the array pointed to by the pointer cp, neither pos nor n has a default value // Comparing s with s2 s.compare(s2); // Compare n1 characters in s starting with pos1 subscript with s2 s.compare(pos1, n1, s2); // Compare n1 characters from pos1 subscript in s with n2 characters from pos2 in s2 s.compare(pos1, n1, s2, pos2, n2); // Compare s to C-style empty character-terminated strings pointed to by pointer cp s.compare(cp); // Compare n1 characters starting with pos1 subscript in s with C-style string ending with empty character pointed to by pointer cp s.compare(pos1, n1, cp); // Compare n1 characters starting with pos1 subscript in s with the first n2 characters of a C-style empty string pointed to by pointer cp s.compare(pos1, n1, cp, n2);
In addition to sequential containers, the Standard Library provides three sequential container adapters: queue, priority_queue, and stack adapters. Adapters are common concepts in the Standard Library, including container adapters, iteration adapters, and function adapters. Essentially, adapters are a mechanism for making one thing behave like another. Container adapters allow an existing container type to be picked upImplemented in a different abstract type of work. For example, a stack adapter allows any sequential container to work as a stack, with default stack and queue built on the deque ue container and priority_queue built on the vector s container.