The Standard Template Library (STL) in C++ is one of the most commonly used libraries. STL provides a lot of algorithms and data structures, helping to simplify the process of developing code.
Within the STL, the vector is one of the most popular data structures and has some benefits over a conventional array. Read on to discover exactly how vectors in C++ work and how they can be used.
What Are Vectors In C++ STL?
Simply put, a vector is a type of data structure known as a dynamic array. This differs from a more traditional array in that a vector’s size can be changed during execution. This is what makes vectors a dynamic structure.
As such, vectors are most helpful when you need to store elements and adjust their size over time. It should be noted that vectors always contain elements of an identical data type, such as strings or integers.
Vectors also have the advantage of being able to be traversed using iterators, since their elements are stored contiguously.
How Do You Use Vectors?

©History-Computer.com
To use vectors, you must include the “vector” header file, as this is the file within which they’re defined. Next, you’ll need to create a vector by declaring a variable and indicating the data type of your desired elements. For example:
std::vector<int> number;
where std is an abbreviation for the STL, “int” is the type of vector (namely, integer), and “number” is the name of the vector.

©History-Computer.com
After this, you need to initialize the vector, meaning you must assign a value to the “int” variable as a starting point. Generally, this can be done in two ways, directly or indirectly, by providing these values to the vector. To directly provide the values, we use the following code:
#include <vector>
#include <iostream>
int main() {
std::vector<int> vectora {2, 4, 6, 8, 10};
for (int i : vectora) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
This will produce a vector with 2, 4, 6, 8, and 10 as its elements, and print the output to the console. To indirectly initialize, you can simply declare the size and value of the vector, as follows:
vector<int> vectorb(10, 2);
This will produce a vector of size 10, with each element being equal to 2. These results are shown in the screenshots above.
How Can Vectors in C++ STL Be Used?
There are many ways to use vectors in C++ STL, depending on your goals. We’ll go through some of the most common ways, with examples.
Iterators

©History-Computer.com
These are object types used to traverse elements within the vector. Much like pointers, iterators can be incremented and decremented, as well as used to obtain the value of the element pointed to. The types of iterators are:
- begin(): This returns an iterator that points to the first vector element.
- end(): The returned iterator here points to the element that would theoretically follow the last vector element.
- rbegin(): Instead of the first, the returned iterator points to the last element, i.e. a reversed beginning.
- rend(): The iterator here points to the theoretical element preceding the first element.
- cbegin() and cend(): Similar to begin() and end(), except the iterator is constant, meaning it cannot modify the value it’s pointing to.
- crbegin() and crend(): Similar to rbegin() and rend(), but with a constant iterator.
The following code illustrates every kind of iterator that can be used with vectors.
#include <iostream>
#include <vector>
int main() {
// Create a vector of integers
std::vector<int> vec{1, 2, 3, 4, 5};
// 1. Using a regular for loop with an index variable
for (std::size_t i = 0; i < vec.size(); i++) {
std::cout << vec[i] << " ";
}
std::cout << std::endl;
// 2. Using an iterator
for (auto it = vec.begin(); it != vec.end(); it++) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 3. Using a const_iterator (to iterate over a const vector)
const std::vector<int> const_vec{6, 7, 8, 9, 10};
for (auto it = const_vec.cbegin(); it != const_vec.cend(); it++) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 4. Using a reverse_iterator (to iterate in reverse order)
for (auto it = vec.rbegin(); it != vec.rend(); it++) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 5. Using a const_reverse_iterator (to iterate over a const vector in reverse order)
for (auto it = const_vec.crbegin(); it != const_vec.crend(); it++) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}
Code Explanation
Here, we’re using for loops to iterate over the vector “vec.” For the constant iterators, we create a second vector called “const_vec.”
Capacity Functions

©History-Computer.com
The amount of functions that can be used with vectors is vast, but functions to do with assessing and changing the size of the vector are very common. Functions concerning capacity are described as follows:
- size(): This returns the size of the vector, i.e. the number of elements.
- max_size(): This returns the maximum number of elements the vector can hold.
- resize(n): Resizes the vector so that it contains “n” number of elements.
- capacity(): This returns the number of elements the vector can currently hold without increasing its memory allocation.
- empty(): Checks whether the vector is empty or not.
- shrink_to_fit(): This decreases the capacity of the vector to fit only its current elements.
- reserve(): This “reserves” space in the vector for a given number of elements.
As before, we’ve demonstrated how to use these functions with an example, which is shown next.
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec;
std::cout << "Initial size of vec: " << vec.size() << std::endl;
std::cout << "Max size of vec: " << vec.max_size() << std::endl;
vec.reserve(10);
std::cout << "Capacity of vec after reserving 10 elements: " << vec.capacity() << std::endl;
for (int i = 0; i < 5; i++) {
vec.push_back(i);
}
std::cout << "Size of vec after adding 5 elements: " << vec.size() << std::endl;
vec.resize(10);
std::cout << "Size of vec after resizing to 10 elements: " << vec.size() << std::endl;
if (vec.empty()) {
std::cout << "Vector is empty." << std::endl;
} else {
std::cout << "Vector is not empty." << std::endl;
}
vec.shrink_to_fit();
std::cout << "Capacity of vec after shrinking to fit its size: " << vec.capacity() << std::endl;
return 0;
}
Code Explanation
First, we initialized the vector “vec”, and then printed the initial and max size. Next, space for 10 elements is reserved, and then 5 elements are added. After this, the vector is resized to a size of 10 elements, the vector is checked for emptiness, and then shrunk to fit. The results at every stage are printed, as shown in the image.
Accessing Elements

©History-Computer.com
Having access to the elements in your vector is almost as important as modifying the contents. The functions that are used to access elements are:
- operator(): This accesses the element at the specified vector index.
- at(): This also accesses the element at a specified index, except it give. an “std::out_of_range” exception if the index is out of range.
- front(): This returns a reference to the first vector element.
- back(): As with front, but with the last vector element.
- data(): This returns the first element’s pointer.
We can illustrate these functions with the code below.
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
std::cout << "Element at index 2: " << vec[2] << std::endl;
try {
std::cout << "Element at index 6: " << vec.at(6) << std::endl;
} catch (const std::out_of_range& e) {
std::cerr << "Out of range exception: " << e.what() << std::endl;
}
std::cout << "First element: " << vec.front() << std::endl;
std::cout << "Last element: " << vec.back() << std::endl;
int* ptr = vec.data();
std::cout << "Elements in vector: ";
for (std::size_t i = 0; i < vec.size(); ++i) {
std::cout << *(ptr + i) << " ";
}
std::cout << std::endl;
return 0;
}
Code Explanation
To start, we create the vector “vec” and initialize it with 5 elements. The second element is accessed using operator(). The at() function then attempts to access the 6th element, but this doesn’t exist, so an error message is produced using the try-catch block.
The first and last elements are then accessed with front() and back(), respectively, and then the data() function points to each element incrementally, and all the results are printed. You can see the output in the screenshot.
Modifying Elements

©History-Computer.com
Now we’ve covered how to access your vector elements, assess the vector capacity and traverse the vector, it’s time to show how to modify the contents. The functions used to modify the elements are as follows:
- assign(): This assigns a new value to vector elements, replacing the old values.
- push_back(): This “pushes” the elements in question into the back of the vector.
- pop_back(): Instead of adding elements to the back, this removes elements from the back.
- insert(): New elements are added before the specified element.
- erase(): The elements at the specified position are removed.
- clear(): All elements of the vector are removed.
- swap(): The contents of each specified vector are swapped with one another.
- emplace(): The vector is extended by creating an element at the specified position, rather than simply copying the value in.
- emback(): Similar to emplace(), except the element is added to the back of the vector.
To illustrate these functions, consider the following code:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec {1, 2, 3};
vec.assign({4, 5, 6});
vec.push_back(7);
vec.pop_back();
vec.insert(vec.begin() + 1, 8);
vec.erase(vec.begin() + 1);
std::vector<int> vec2 {10, 20, 30};
vec.swap(vec2);
vec.clear();
vec.emplace(vec.begin(), 9);
vec.emplace_back(11);
std::cout << "vec: ";
for (int i : vec) {
std::cout << i << " ";
}
std::cout << "\nvec2: ";
for (int i : vec2) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
Code Explanation
We begin by creating the vector “vec”, with values {1, 2, 3.} Assign() is then used to replace these values with {4, 5, 6.} The element 7 is then pushed to the back of the vector, giving {4, 5, 6, 7.}
7 is then removed from the vector, and the element 8 is inserted before the second vector element, giving values {4, 8, 5, 6.} The second element is then erased, which was the element we just added.
We then create “vec2”, and the contents of both vectors are swapped, so that “vec” is equal to {10, 20, 30} and “vec2” is equal to {4, 5, 6.} All of the elements are now removed from “vec”, an element of 9 is inserted into “vec” at the first position and an element of 11 is inserted into the end of “vec.”
All of this gives “vec” as {9, 11} and “vec2” as {10, 20, 30},” as seen in the screenshot above.
What Are the Time and Space Complexities of Using Vectors?
This does depend on the functions being used, but, generally, most operations have a time complexity of O(1). This is because accessing, inserting, or removing elements doesn’t depend on the vector size, so long as elements aren’t being added at the end and the array isn’t resized.
When modifying elements in the middle, the time complexity is often O(n), as this depends on shifting the other elements. The space complexity is equal to O(n), as it’s proportional to the size of the vector.
Vectors In C++ STL: Wrapping Up
Overall, vectors are a key component of the C++ STL, and they’re largely used for their dynamic resizing capabilities. Accessing elements uses constant time, and many functions can be used efficiently with vectors. While they can be memory intensive because of their resizing ability, vectors are a flexible data structure that all C++ programmers should be aware of.
The image featured at the top of this post is ©Monstar Studio/Shutterstock.com.