vector guide

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:

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`.


edit this page