Using std::vector

In [1]:
#include <vector>
#include <iostream>

template <typename T>
void printVector (const std::vector<T>& v) {
    // traditional for-loop
    for (size_t i = 0; i < v.size(); ++i) {
        std::cout << v[i] << ' ';
    }
    std::cout << '\n';
}

template <typename T>
void printVector2 (std::vector<T> const& v) {
    // range-based for-loop
    for (auto val : v) {
        std::cout << val << ' ';
    }
    std::cout << '\n';
}

Pass-by-value vs. Pass-by-reference

In [2]:
template <typename T>
void addFourByValue(std::vector<T> vec, T value) {
    vec.push_back(value);
    vec.push_back(value);
    vec.push_back(value);
    vec.push_back(value);
}

template <typename T>
void addFourByRef(std::vector<T>& vec, T value) {
    vec.push_back(value);
    vec.push_back(value);
    vec.push_back(value);
    vec.push_back(value);
}

Sequenced operations on std::vector

In [3]:
std::vector<int> a {1, 5, 2, 4, 7};
printVector(a);
1 5 2 4 7 
In [4]:
a.push_back(15);
printVector(a);
1 5 2 4 7 15 
In [5]:
a.erase(a.begin());
printVector2(a);
5 2 4 7 15 
In [6]:
std::vector<int> b (a.end() - 3, a.end());
printVector2(b);
4 7 15 
In [7]:
addFourByValue(b, 12);
printVector(b);
4 7 15 
In [8]:
addFourByRef(b, 12);
printVector(b);
4 7 15 12 12 12 12 
In [9]:
std::cout << "b.at(14) is " << b.at(14) << '\n';
b.at(14) is 
Standard Exception: vector::_M_range_check: __n (which is 14) >= this->size() (which is 7)
In [10]:
std::cout << "b[14] is " << b[14] << '\n';
b[14] is 81

Common bugs with std::vector

In [11]:
std::vector<int> d;
d
Out[11]:
{}
In [ ]:
std::cout << "size: " << d.size() << '\n';
std::cout << "capacity: " << d.capacity() << '\n';
std::cout << "data ptr: "<< d.data() << '\n';
std::cout << std::endl;
for (int i = 0; i < 10; ++i) {
    d[i] = 4;
}
d
size: 0
capacity: 0
data ptr: 0

The correct way
In [12]:
std::vector<int> e(10);
e
Out[12]:
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
In [13]:
std::cout << "size: " << e.size() << '\n';
std::cout << "capacity: " << e.capacity() << '\n';
std::cout << "data ptr: "<< e.data() << '\n';
for (int i = 0; i < 10; ++i) {
    e[i] = 4;
}
e
size: 10
capacity: 10
data ptr: 0x55eff6cd7fc0
Out[13]:
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }
Alternatively, use push_back
In [14]:
std::vector<int> f;
std::cout << "size: " << f.size() << '\n';
std::cout << "capacity: " << f.capacity() << '\n';
std::cout << "data ptr: "<< f.data() << '\n';
f
size: 0
capacity: 0
data ptr: 0
Out[14]:
{}
In [16]:
for (int i = 0; i < 10; ++i) {
    f.push_back(4);
}
std::cout << "size: " << f.size() << '\n';
std::cout << "capacity: " << f.capacity() << '\n';
std::cout << "data ptr: "<< f.data() << '\n';
f
size: 10
capacity: 16
data ptr: 0x55eff7045770
Out[16]:
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }
In [ ]: