Include Header
#include <vector>
Declaration
std::vector<Type> vec_name;
Insertion
vec_name.push_back(value); // Add to end
vec_name.insert(vec_name.begin() + index, value); // Insert at position
Access Element
Type val = vec_name[index]; // Direct access
Type val = vec_name.at(index); // Bounds-checked access
Check if Empty
if (vec_name.empty()) {
// Vector is empty
}
Erase Element
vec_name.erase(vec_name.begin() + index); // Remove at index
vec_name.clear(); // Remove all elements
Iterate Through Elements
for (const auto& val : vec_name) {
std::cout << val << std::endl;
}
In reverse order:
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
std::cout << *it << " ";
}
Reverse the order of a Vector
std::reverse(vec.begin(), vec.end());
Size and Capacity
vec_name.size(); // Number of elements
vec_name.capacity(); // Allocated storage capacity
vec_name.resize(new_size); // Resize vector
Other Useful Functions
vec_name.front(); // First element
vec_name.back(); // Last element
vec_name.pop_back(); // Remove last element
Check if Element Exists
#include <algorithm>
if (std::find(vec_name.begin(), vec_name.end(), value) != vec_name.end()) {
// Element found
} else {
// Element not found
}
Ways to Construct a Vector
// Empty vector
std::vector<int> v1;
// Vector with 5 default-initialized ints (0)
std::vector<int> v2(5);
// Vector with 5 elements, each initialized to 42
std::vector<int> v3(5, 42);
// Copy constructor
std::vector<int> v4 = v3;
// Move constructor
std::vector<int> v5 = std::move(v3);
// Construct from initializer list
std::vector<int> v6 = {1, 2, 3, 4, 5};
// Construct from array
int arr[] = {10, 20, 30};
std::vector<int> v7(std::begin(arr), std::end(arr));
// Construct from iterators
std::vector<int> source = {5, 6, 7};
std::vector<int> v8(source.begin(), source.end());
Filter a Vector
To create a filtered vector based on some property of the elements, use std::copy_if or C++20 std::ranges::copy_if. Here are two examples:
C++11 and later:
#include <vector>
#include <algorithm>
std::vector<int> original = {1, 2, 3, 4, 5, 6};
std::vector<int> filtered;
std::copy_if(original.begin(), original.end(), std::back_inserter(filtered),
[](int x) { return x % 2 == 0; }); // Keep even numbers
C++20 (with ranges):
#include <vector>
#include <ranges>
std::vector<int> original = {1, 2, 3, 4, 5, 6};
std::vector<int> filtered;
std::ranges::copy_if(original, std::back_inserter(filtered),
[](int x) { return x % 2 == 0; }); // Keep even numbers
Join Two Vectors
To join or concatenate two vectors, you can use std::insert to append the contents of one vector to the end of another:
#include <vector>
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = {4, 5, 6};
// Append v2 to v1
v1.insert(v1.end(), v2.begin(), v2.end());
After this, v1 contains {1, 2, 3, 4, 5, 6}.
If you want to create a new vector that is the result of joining two vectors:
#include <vector>
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = {4, 5, 6};
std::vector<int> joined;
joined.reserve(v1.size() + v2.size()); // Optional, to improve performance
joined.insert(joined.end(), v1.begin(), v1.end());
joined.insert(joined.end(), v2.begin(), v2.end());
Vector Constructors and Operations: When They Are Called
In C++, different vector operations can trigger different constructors (copy, move, or default), for the objects that it holds. Understanding this is important to avoid unnecessary copies, improve performance, and correctly manage resources.
1. Push Back
std::vector vec; MyClass obj;
// Copy version
vec.push_back(obj); // Calls MyClass copy constructor
// Move version (C++11+)
vec.push_back(std::move(obj)); // Calls MyClass move constructor
Note: Using std::move avoids copying large objects unnecessarily.
2. Insert
vec.insert(vec.begin() + 2, obj); // Copy constructor called
vec.insert(vec.begin() + 2, std::move(obj)); // Move constructor called
If inserting a range of elements, move constructors are used if available:
std::vector other = {...}; vec.insert(vec.end(), std::make_move_iterator(other.begin()), std::make_move_iterator(other.end())); // Moves elements from other
3. Resize
vec.resize(10); // Default constructor called for new elements
vec.resize(10, obj); // Copy constructor called for new elements
4. Erase
vec.erase(vec.begin() + 3);
When you erase an element from a vector, all elements after the erased element are **shifted left**. This triggers either:
- Move constructor (if available and noexcept)
- Copy constructor (if move is not available)
For example, if MyClass has a move constructor, erase will use moves instead of copies to shift elements.
5. Copying a Vector
std::vector vec2 = vec; // Copy constructor of MyClass called for each element
6. Moving a Vector
std::vector vec2 = std::move(vec); // Move constructor of vector is called // Individual MyClass move constructors are generally NOT called // because vector just transfers ownership of its internal buffer
7. Emplace Operations
vec.emplace_back(args...); // Constructs MyClass in-place (no copy or move) vec.emplace(vec.begin(), args...); // Constructs in-place at specific position
Note: emplace avoids unnecessary construction and copying/moving by constructing elements directly inside the vector.
Summary Table
| Operation | Constructor Called |
|---|---|
| push_back(obj) | Copy constructor |
| push_back(std::move(obj)) | Move constructor |
| insert(position, obj) | Copy constructor |
| insert(position, std::move(obj)) | Move constructor |
| resize(new_size) | Default constructor for new elements |
| resize(new_size, obj) | Copy constructor for new elements |
| erase(position) | Move constructor (if available) for shifting elements |
| vector copy | Copy constructor for each element |
| vector move | Move constructor of vector; elements usually not moved |
| emplace / emplace_back | In-place constructor (no copy or move) |
Understanding these rules helps optimize performance, especially for classes with expensive copy operations like `IVPColor`.