std::vector
is a dynamic array with continuous physical storage space. There is no need to specify its size, which will expand as needed. compared to normal arrays, std::vector
provides many APIs.
Get Started
- Adds an element to its end:
push_back
- Removes the last element:
pop_back
- Returns the number of elements:
size
- How to iterate over a std::vector
#include <iostream>
#include <vector>
int main()
{
std::vector<int> container;
container.push_back(1);
container.push_back(2);
container.push_back(3);
container.push_back(4);
container.push_back(5);
for (int i = 0; i < container.size(); ++i) std::cout <<
container[i] << ' ';
std::cout << std::endl;
container.pop_back();
container.pop_back();
for (auto& e : container) std::cout << e << ' ';
std::cout << std::endl;
}
Novice
- Erases elements:
erase
- Clears the contents:
clear
- Use user-defined types
- Reference parameter to avoid copies
#include <iostream>
#include <vector>
struct Vertex
{
float x, y, z;
};
std::ostream& operator<<(std::ostream& stream, const Vertex& vertex)
{
stream << vertex.x << ", " << vertex.y << ", " << vertex.z;
return stream;
}
void Print(const std::vector<Vertex>& vertices)
{
std::cout << "----------------------------------------" <<
std::endl;
for (auto& v : vertices) std::cout << v << std::endl;
std::cout << "----------------------------------------" <<
std::endl;
}
int main()
{
std::vector<Vertex> vertices;
vertices.push_back({ 1, 2, 3 });
vertices.push_back({ 4, 5, 6 });
vertices.push_back({ 7, 8, 9 });
vertices.push_back({ 10, 11, 12 });
vertices.push_back({ 13, 14, 15 });
vertices.push_back({ 16, 17, 18 });
Print(vertices);
vertices.erase(vertices.begin() + 1); // Delete index 1
Print(vertices);
vertices.erase(vertices.begin() + 2, vertices.end() - 1); //
Delete index 2, 3
Print(vertices);
vertices.clear(); // No any element
Print(vertices);
}
- Returns the number of elements that can be held in currently allocated storage:
capacity
- Reserves storage(specify the allocated storage):
reserve
- Constructs an element in-place at the end:
emplace_back
- Two methods to avoid unnecessary copies.
#include <iostream>
#include <vector>
struct Vertex
{
float x, y, z;
Vertex(float x, float y, float z)
: x(x), y(y), z(z)
{
}
Vertex(const Vertex& vertex)
: x(vertex.x), y(vertex.y), z(vertex.z)
{
std::cout << "Copied!" << std::endl;
}
};
void PrintCapacity(const std::vector<Vertex>& vertices)
{
std::cout << vertices.capacity() << std::endl;
}
int main()
{
// The code that can be optimized.
std::cout << "----------------------------------------" <<
std::endl;
{
std::vector<Vertex> vertices;
vertices.push_back({ 1, 2, 3 });
PrintCapacity(vertices);
vertices.push_back({ 4, 5, 6 });
PrintCapacity(vertices);
vertices.push_back({ 7, 8, 9 });
PrintCapacity(vertices);
}
// Method 1: use reserve to avoid resizing capacity to decrease
copies.
std::cout << "----------------------------------------" <<
std::endl;
{
std::vector<Vertex> vertices;
vertices.reserve(3);
PrintCapacity(vertices);
vertices.push_back({ 1, 2, 3 });
vertices.push_back({ 4, 5, 6 });
vertices.push_back({ 7, 8, 9 });
PrintCapacity(vertices);
}
// Method 2: use emplace_back to efficiently construct element
inside the vector container.
std::cout << "----------------------------------------" <<
std::endl;
{
std::vector<Vertex> vertices;
vertices.reserve(3);
vertices.emplace_back(1, 2, 3);
vertices.emplace_back(4, 5, 6);
vertices.emplace_back(7, 8, 9);
}
std::cout << "----------------------------------------" <<
std::endl;
}
Intermediate
- Access the first element:
front
- Access the last element:
back
- Direct access to the underlying array:
data
- Changes the number of elements stored(logic size):
resize
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
std::cout << "------------front/back------------" << std::endl;
std::cout << v.front() << std::endl;
v.front() = 100; // this will change v[0]
std::cout << v[0] << std::endl;
std::cout << v.back() << std::endl;
std::cout << "------------data------------" << std::endl;
int* p = v.data();
std::cout << (&(v.front()) == p) << std::endl; // 1
std::cout << *p << std::endl;
std::cout << p[1] << std::endl;
std::cout << "------------resize------------" << std::endl;
for (auto& e : v) std::cout << e << " ";
std::cout << std::endl;
v.resize(5, -1);
for (auto& e : v) std::cout << e << " ";
std::cout << std::endl;
std::cout << "size=" << v.size() << " capacity=" << v.capacity()
<< std::endl; // both increase
}
- Reduces memory usage by freeing unused memory:
shrink_to_fit
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v;
for (int i = 0; i < 100000; ++i) v.push_back(i);
v.resize(3);
std::cout << "size=" << v.size() << std::endl;
std::cout << "capacity=" << v.capacity() << std::endl;
std::cout << "-----------------------------------------" <<
std::endl;
v.shrink_to_fit();
std::cout << "size=" << v.size() << std::endl;
std::cout << "capacity=" << v.capacity() << std::endl;
}
- Inserts elements:
insert
#include <iostream>
#include <vector>
void Print(const std::vector<int>& v)
{
for (auto& e : v) std::cout << e << " ";
std::cout << std::endl;
}
int main()
{
std::vector<int> v;
v.emplace_back(1);
v.emplace_back(2);
v.emplace_back(3);
Print(v);
std::cout << "------------insert(v.begin(), 100)------------" <<
std::endl;
v.insert(v.begin(), 100); // insert at index 0
Print(v);
std::cout << "------------insert(v.begin(), 2, 1000)------------"
<< std::endl;
v.insert(v.begin(), 2, 1000); // insert 2 items at index 0
Print(v);
std::cout << "------------insert(std::next(v.begin(), 3),
other.begin(), other.end())------------" << std::endl;
std::vector<int> other(2, 666);
v.insert(std::next(v.begin(), 3), other.begin(), other.end()); //
insert a range at index 3
Print(v);
std::cout << "------------insert(v.begin(), arr, arr +
std::size(arr))------------" << std::endl;
int arr[3] = { 888, 888, 888 };
v.insert(v.begin(), arr, arr + std::size(arr)); // insert a array
at index 0
Print(v);
std::cout << "------------insert(v.end(), { 999, 999
})------------" << std::endl;
v.insert(v.end(), { 999, 999 }); // insert literals
Print(v);
}
Advanced or Master
Life is short. keep it simple. 😅