15.8. Growing sequences with std::vectorΒΆ

std::vector is declared in <vector>. It owns a sequence whose size can change at run time. push_back appends an element, pop_back removes the last element of a nonempty vector, and size() reports the number of stored elements. Unlike an array's extent, a vector's size is not part of its type.

A vector's capacity is the number of elements it can hold before it must allocate more storage. reserve(n) can increase capacity, but does not add elements. resize(n) changes the number of elements. Prefer push_back when reading an unknown number of records instead of maintaining a separate count of used slots yourself.

Example c192_vectors_growth
 1#include <iostream>
 2#include <sstream>
 3#include <vector>
 4
 5int main() {
 6    std::istringstream input("12 7 19");
 7    std::vector<int> readings;
 8    readings.reserve(10);
 9    int value = 0;
10    while (input >> value) {
11        readings.push_back(value);
12    }
13    std::cout << readings.size() << '\n';
14    for (int reading : readings) {
15        std::cout << reading << ' ';
16    }
17    std::cout << '\n';
18}

The vector contains three elements, not ten. Its capacity is at least ten; the exact capacity is an implementation detail. A vector may contain repeated values. Appending can invalidate references, pointers, and iterators to its elements when storage is reallocated; do not keep using them after that happens.

For a table whose dimensions are known only at run time, create rows with std::vector<std::vector<int>>. This initialization creates a rectangular table of zeros:

Example c192_vectors_table
 1#include <cstddef>
 2#include <iostream>
 3#include <vector>
 4
 5int main() {
 6    std::size_t rows = 2;
 7    std::size_t columns = 3;
 8    std::vector<std::vector<int>> table(rows, std::vector<int>(columns, 0));
 9    table.at(1).at(2) = 7;
10    for (const auto& row : table) {
11        for (int value : row) {
12            std::cout << value << ' ';
13        }
14        std::cout << '\n';
15    }
16}

Each row is a separate vector and can have a different length. If your algorithm requires a rectangular table, preserve that condition when resizing rows. Check both dimensions when accessing a value; table.at(r)[c] checks only the row. A table with no rows has no first row from which to read a width.

We want to open a file and parse its data into our program. What library do we need to include?