A Resizable Container with std::vector
A std::vector is a container from the standard library that holds a sequence of elements, all of the same type, and can grow or shrink while your program runs. Think of it as an array that manages its own size.
To use it, include the <vector> header:
A few things to notice here:
- Line 5: The
<int>afterstd::vectortells the compiler what type of elements this vector will hold, in this case, integers. - Line 6–8: The
push_backmethod adds a new element to the end of the vector, and its capacity adjusts automatically to make room. - Line 10–12: You can loop over a vector just like you do over an array.
Declaring and initializing vectors
You can start with an empty vector and fill it later, like above, or you can initialize it with values right away:
std::vector<double> temperatures = {98.6, 99.1, 97.8, 100.2};You can also create a vector of a given size, with every element set to the same starting value:
std::vector<int> scores(10, 0); // 10 elements, all set to 0The first number is how many elements you want, and the second is the value to fill them with.
Checking the size
A vector’s current size is always available through .size():
Accessing individual elements
You can access individual elements with square brackets, just like an array:
std::cout << names[0] << "\n"; // Alicenames[1] = "Robert"; // change the second nameIndexing still starts at 0, so names[0] is the first element, names[2] is the third, and in general the last element is names[names.size() - 1].
Just like arrays, if you use an index out of bounds, it results in undefined behavior. A safer alternative is .at(), which stops the program with a clear message if the index is out of range:
std::cout << names.at(10); // throws an error you can actually understandFor the first and last elements specifically, .front() and .back() save you from spelling out the index explicitly:
Adding, removing, and checking for empty
Besides push_back, a few other operations come up constantly:
- Line 10:
pop_backremoves the last element. - Line 11:
empty()returnstrueorfalsedepending on whether the vector has any elements. This is often clearer to read than checkingsize() == 0. - Line 14:
clear()wipes the vector down to zero elements.
This has been a first look at std::vector. There’s more underneath, how it grows internally, and what really happens to that memory when the vector shrinks. We’ll get into all of that later in the second part of this course.
Looping with a reference
std::vector<std::vector<int>> is a vector whose elements are themselves std::vector<int>, a vector of vectors.
You can use this to represent a grid or table (see lines 5–9), where the outer vector holds the rows, and each row is its own vector of values:
Notice how a range-based loop is used on line 11 to print the values in the grid. Each round of the for loop makes a fresh copy of an inner vector. To avoid this duplication, we may want to loop with a const reference instead:
Checkpoint
What does this declaration create?
std::vector<int> target(5, 100);Suppose cart holds 3 elements. What does cart.empty() do?
Given this code, what is queue.size() at the end?
std::vector<int> queue = {1, 2, 3, 4};
queue.pop_back();
queue.push_back(9);
queue.pop_back();