C Primier Plus Sequential Container

vector deque list forward-list array string
string and vector hold their elements in contiguous memory.
it is best to use vector unless there is a good reason to prefer another container.
the predominant operation of the application (whether it does more access or more insertion or deletion) will determine the choice of container type.
The exception is that the forward_list iterators do not support the decrement (–) operator.
a reverse iterator is an iterator that goes backward through a
container and inverts the meaning of the iterator operations. For example, saying ++ on a reverse iterator yields the previous element.

When write access is not needed, use cbegin and cend.
When we initialize a container as a copy of another container, the container type and element type of both containers must be identical.

1
2
3
4
5
6
7
list<string> authors = {"Milton", "Shakespeare", "Austen"};
vector<const char*> articles = {"a", "an", "the"};
list<string> list2(authors); // ok: types match
deque<string> authList(authors); // error: container types don't match
vector<string> words(articles); // error: element types must match
// ok: converts const char* elements to string
forward_list<string> words(articles.begin(), articles.end());

Sequential Container Size-Related Constructors

1
2
3
4
vector<int> ivec(10, -1); // ten int elements, each initialized to -1
list<string> svec(10, "hi!"); // ten strings; each element is "hi!"
forward_list<int> ivec(10); // ten elements, each initialized to 0
deque<string> svec(10); // ten elements, each an empty string

The constructors that take a size are valid only for sequential containers; they are not supported for the associative containers.
To use an array type we must specify both the element type and the size:

1
2
array<int, 10>::size_type i; // array type includes element type and size.
array<int>::size_type j; // error: array<int> is not a type.

Six Way to Create and Initialize a vector

1
2
3
4
5
6
vector<int> vec; // 0
vector<int> vec(10); // 0
vector<int> vec(10,1); // 1
vector<int> vec{1,2,3,4,5}; // 1,2,3,4,5
vector<int> vec(other_vec); // same as other_vec
vector<int> vec(other_vec.begin(), other_vec.end()); // same as other_vec

  1. The constructor that takes another container as an argument (excepting array) assumes the container type and element type of both containers are identical.
  2. The constructor that takes two iterators as arguments does not require the container types to be identical. Moreover, the element types in the new and original containers can differ as long as it is possible to convert the elements we’re copying to the element type of the container we are initializing.

Unlike built-in arrays, the library array type does allow assignment,the array type does not support assign and it does not allow assignment from a braced list of values.
Using assign (Sequential Containers Only)

1
2
3
4
5
list<string> names;
vector<const char*> oldstyle;
names = oldstyle; // error: container types don't match
// ok: can convert from const char*to string
names.assign(oldstyle.cbegin(), oldstyle.cend());

after swap,with the exception of string,iterators, references, and pointers into the containers are not invalidated.but a call to swap on a string may invalidate iterators, references and pointers.

Relational Operators

Every container type supports the equality operators (== and !=); all the containers except the unordered associative containers also support the relational operators (>,>=, <, <=). The right- and left-hand operands must be the same kind of container and must hold elements of the same type.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ Compare elements in a list<int> to a vector<int>
#include <iostream>
#include <vector>
#include <list>
int main()
{
std::list<int> list{1, 2, 3, 4, 5};
std::vector<int> vec1{1, 2, 3, 4, 5};
std::vector<int> vec2{1, 2, 3, 4};
std::cout << std::boolalpha
<< (std::vector<int>(list.begin(), list.end()) == vec1)
<< std::endl;
std::cout << std::boolalpha
<< (std::vector<int>(list.begin(), list.end()) == vec2)
<< std::endl;
}


Sequential Container Operations

When we use an object to initialize a container, or insert an object into a
container, a copy of that object’s value is placed in the container, not the
object itself.
The insert members are supported for vector, deque, list, and string.
When we pass a pair of iterators, those iterators may not refer to the same container as the one to which we are adding elements.

  1. push or insert member, we pass objects of the element type and
    those objects are copied into the container.
  2. an emplace member, we
    pass arguments to a constructor for the element type. The emplace members use those arguments to construct an element directly in space managed by the container.

Accessing Elements in a sequential container
before calling front or back (or dereferencing the iterators from begin or end), check that container isn’t empty. If the container were empty, the operations inside the if would be undefined.
The members that access elements in a container (i.e., front, back, subscript, and at) return references.
subscript operator does not check whether the index is in range.
If the container holds elements of a class type and resize adds elements the element type must have a default constructor.
Loops that add or remove elements of a vector, string, or deque must cater to the fact that iterators, references, or pointers might be invalidated. The program must ensure that the iterator, reference, or pointer is refreshed on each trip through the loop.
The size of a container is the number of elements it already holds; its capacity is how many elements it can hold before more space must be allocated.

  1. Searching (and other string operations) are case sensitive.
  2. Similarly, the find_last functions behave like the find_first functions, except that they return the last match rather than the first.
  3. find_last_of searches for the last character that matches any element of the search string.
  4. find_last_not_of searches for the last character that does not match any
    element of the search string.

All the containers (except array) provide efficient dynamic memory management.