C++ Tips : std::vector
std::vector
C++ Tips : std::vector
C++ Tips
std::vector
std::vector
1
2
3
4
5
6
7
8
9
10
template<T, A = std::allocator<T>>
class Vector
{
public:
void push_back(const T&); // l-value
void push_back(T&&); // r-value
template<typename ...Args>
void emplace_back(Args&& ...args); // Args&& universal ref
}
- Default allocator used by all STL containers if no user-defined provided.
- Dynamic and contiguous.
- Fast random access.
operator[]
,.at()
- Add elements via
push_back()
oremplace_back()
- If vector is destroyed, then elements dtor will also be called.
- Valid for all containers.
push_back() vs emplace_back()
push_back()
- Takes an already constructed object.
- Rollback if push_back() throws. (No insertion.)
- No return value
emplace_back()
- Forwards arguments to the constructor of the class using std::forward
- Object is
constructed
throughallocator_traits::construct
.
Tip-01
- Non-member iterator func == Member iterator func
- Meaning,
std::crbegin(vec)
is equal tovec.crbegin()
- Meaning,
size() == 0
for all moved containers
Tip-02
1
2
3
4
class A { A(int); }
vector<A> avec(100);
//syntax-error : A does not have def ctor
Tip-03
1
2
3
4
5
6
7
8
9
10
11
vector<int> x(10);
// x.size() -> 10
vector<int> y{10};
// y.size() -> 1, {} is a initializer-list
vector<int> z(10,5);
// size() -> 10 and all elements are 5
vector<int> t{10,5};
// size() -> 2 and elements are 10 and 5
Tip-04 : CTAD
- vector supports CTAD (Class Template Argument Deduction)
1
2
vector ivec{1,3,5};
// equals to -> vector<int> ivec{1,3,5};
Tip-05 : Different containers can’t convert implicitly
1
2
3
4
5
6
7
std::list<int> x {1,3,5};
std::vector<int> y { x };
// syntax-error
std::vector<int> y { x.begin(), x.end() };
// OK
Tip-06
1
2
3
4
5
6
7
8
9
10
int a[] {1,3,5};
// before modern c++
std::vector<int> ivec( a, a + sizeof(a) / sizeof(*a) );
// after modern c++
std::vector<int> ivec2( std::begin(a), std::end(a) );
// std::size(y) == y.size()
// no distinct
Tip-07 : Prefer stl algorithms instead of raw loop
1
2
3
4
5
6
7
8
9
10
for(auto iter = vec.begin(); iter != vec.end(); ++iter) {...}
for(auto x : vec) {...}
// x -> *iter
for(size_t i{}; i < vec.size(); ++i)
{
vec.at(i);
// if index is invalid, exception is thrown
}
Tip-07
1
2
3
4
5
6
7
8
9
10
std::vector<std::string> x { "A", "B" };
std::vector<std::string> y;
y.push_back( std::move(x[0]) );
y.push_back( std::move(x[1]) );
std::cout << x.size() << '\n';
// x.size() -> 2
std::cout << (x[0].empty() ? "EMPTY" : x[0]);
// Output : EMPTY
vector::resize
1
2
3
4
5
6
7
8
9
10
11
vector<int> x{1,2,3};
x.resize(5); // 1,2,3,0,0
x.resize(2); // 1,2
x.resize(6,4); // 1,2,4,4,4,4
x.resize(0) // clears the vector
// x.clear() == x.resize(0)
vector::assign
1
2
3
4
5
6
7
8
9
10
11
12
vector<char> c;
c.assign(5, 'a');
string s(6, 'b');
c.assign(s.begin(), s.end());
// b, b, b, b, b, b
c.assign( {'a', 'b' });
// a, b
vector::insert
- returns iterator that points inserted value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
vector<int> i(2,10); // 10, 10
i.insert(i.begin(), 25); // 25, 10, 10
i.insert(i.begin(), 2, 50); // 50, 50, 25, 10, 10
i.insert(i.end(), {1,2,3}); // 50, 50, 25, 10, 10, 1, 2, 3
int a[] {4,5,6};
i.insert(i.begin(), a, a + size(a));
// 50, 50, 25, 10, 10, 1, 2, 3, 4, 5, 6
vector::erase
- returns iterator pointing that followed the last element erased.
1
2
3
4
5
6
vector<int> x{1,2,3,4,5};
// erase the first 3 elements:
x.erase ( x.begin(), x.begin() + 3 );
vector::swap
1
2
3
4
5
6
7
8
vector<string> a (100, "A");
vector<string> b (100, "B");
std::swap(a,b); // same with a.swap(b);
// no string copy.
// just pointers swapped.
vector::pop_back()
- O(1)
- Removes the last element
vector::max_size
- O(1)
- Returns the maximum num of elems the container is able to hold.
This post is licensed under CC BY 4.0 by the author.