📚 Gaddis (Ch. 16.5)
“The Standard Template Library provides a set of well structured generic C++ components that work together in a seamless way.”
- Alexander Stepanov & Meng Lee, The Standard Template Library
vector, list, dequeset, multiset, map, multimapstack, queue, priority_queueiterator, const_iterator, value_type, etc.operator<stack, queue, priority_queuestd::vectorSTL’s std::vector is essentially a dynamic array.
push_back() and pop_back() sequential (end) access.[])vectors know their own size!std::vector Exampleusing std::vector;
using std::string;
// [...]
vector<string> v; // create vector
v.push_back("The number is 10"); // push some values
v.push_back("The number is 20"); // into it...
v.push_back("The number is 30");
cout << "Loop by index:" << endl;
for(vector<string>::size_type i=0; // size type is unsigned
i < v.size(); // vector knows its size!
i++){ // print values by
cout << v[i] << endl; // indexing the
} // vector like an arrayHINT: Use v.at(i) instead of v[i] to enable bounds-checking!
std::vector Example 2std::vector<std::string> v; // create vector
v.push_back("The number is 10"); // push some values
v.push_back("The number is 20"); // into it...
v.push_back("The number is 30");
cout << "Loop by range using iterators:" << endl;
for(auto it = v.begin(); // iterator
it != v.end(); // runs from begin()
++it) // to end(), one at a time
{ // and is
cout << *it << endl; // dereferenced to
} // print the value*) is used to “follow the arrow” to get the value an iterator is pointing to.std::vector Example 3std::vector<std::string> v; // create vector
v.push_back("The number is 10"); // push some values
v.push_back("The number is 20"); // into it...
v.push_back("The number is 30");
cout << "Loop by range-based `for`:" << endl;
for( auto item : v ){ // for each item in v
cout << item << endl; // print the item
}std::vector Example 4auto v = std::vector<std::string>{3}; // pre-size to 3
int n = 1;
for( auto& item : v){ // each item (by ref.)
item = std::string{"The number is "} // generate message
+ std::to_string(10 * n++); // and store in item
}
cout << "Loop by range:" << endl;
for( auto item : v ){ // for each item
cout << item << endl; // print the item
}std::to_string() is contained in <std::string>
Iterators are a generalization of pointers.
++)++ and --)vector ModifiersThese are algorithms that vectors know how to apply to themselves:
clear() : clears all contents (empties the container)
erase() : erase one element, given an iterator to it
insert() : inserts element before a position (given an iterator)
pop_back() : removes the last element
push_back() : adds a new element at the end
resize() : changes the size of the vector
[...] There are others not shown here
clear()Empties the vector.
erase(it_target)Erases the element pointed to by the iterator it_target.
std::vector<int> v{4,8,15,16,23,42,108};
std::vector<int>::iterator target = v.begin();
// Move target to the third element:
target += 2; // by skipping the first two
v.erase(target); // erases the third element
for( auto value : v ){
std::cout << value << '\t';
}4 8 16 23 42 108
insert( it_position, value )Inserts value at the position pointed to by the iterator it_position, shifting current values \(\ge\) it_position to the right.
std::vector<int> v{4,8,16,23,42,108};
v.insert(v.begin() + 2, 15); // insert before 16
for( auto value : v ){
std::cout << value << '\t';
}4 8 15 16 23 42 108
pop_back( )Removes the last value in the vector.
std::vector<int> v{4,8,15,16,23,42,108};
v.pop_back();
for( auto value : v ){
std::cout << value << '\t';
}4 8 15 16 23 42
push_back( )Adds a new value at the end.
std::vector<int> v{4,8,15,16,23,42};
v.push_back(108);
for( auto value : v ){
std::cout << value << '\t';
}4 8 15 16 23 42 108
resize( )Changes size of the vector. Use this to pre-allocate:
std::vector<int> v;
v.resize(10);
for(int i = 0; i < v.size(); ++i){
v.at(i) = (i+1);
}
for( auto value : v ){
std::cout << value << '\t';
}1 2 3 4 5 6 7 8 9 10
vectors to functionsstd::vector is an object type, meaning that it is passed by value by default! This means that even though it “looks and feels” like an array, the argument-to-parameter communication mechanism is quite different.
Let’s look at an example…
Example: Vectors as parameters VS arrays as parameters
First, the “main” part of the program, which will utilize two overloaded functions:
#include <iostream>
#include <vector>
void example(int a[], int size);
void example(std::vector<int> v);
void print_all(int a[], int size);
void print_all(std::vector<int> v);
int main(){
int a[]{1, 2, 3, 4, 5};
std::vector<int> v {1, 2, 3, 4, 5};
example(a, 5);
example(v);
print_all(a, 5);
print_all(v);
return 0;
}Example: Vectors as parameters VS arrays as parameters
void example(int a[], int size){
for(int i = 0; i < size; ++i)
a[i] *= 2;
}
void example(std::vector<int> v){
for(std::vector<int>::size_type i = 0; i < v.size(); ++i)
v[i] *= 2;
}
void print_all(int a[], int size){
for (int i = 0; i < size; ++i)
std::cout << a[i] << '\t';
std::cout << '\n';
}
void print_all(std::vector<int> v){
for(auto value : v)
std::cout << value << '\t';
std::cout << '\n';
}Example: Vectors as parameters VS arrays as parameters
Here is the relevant part of the main program again…
What output do you expect from this code?
Example: Vectors as parameters VS arrays as parameters
Here is the output:
Is that what you expected?
The std::vector is passed by value, so the elements are not modified in the caller (main) even though they were modified in the example function.
We can pass by reference if we want to. While we’re at it, let’s use const qualifiers to add safety guarantees to the printing functions.
void example(int a[], int size){
for(int i = 0; i < size; ++i)
a[i] *= 2;
}
void example(std::vector<int>& v){
for(std::vector<int>::size_type i = 0; i < v.size(); ++i)
v[i] *= 2;
}
void print_all(const int a[], int size){
for (int i = 0; i < size; ++i)
std::cout << a[i] << '\t';
std::cout << '\n';
}
void print_all(const std::vector<int>& v){
for(auto value : v)
std::cout << value << '\t';
std::cout << '\n';
}Now, the output - without changing main() at all:
Hint: Prefer to pass a vector (or other STL container) by const reference (or plain reference if you want to modify it in the function) unless there is a “good reason” to make a copy.
STL and Vectors

CS 50x2 Accelerated Programming Series