The C++ Standard Template Library, included in C++11, is a high-quality library of implementations of the best algorithms and data structures at your fingertips (with plenty of documentation). The implementations are entirely in .h files, so there is no linking necessary.
Some things contained in the STL:
The STL uses a lot of C++ features in its implementation, including:
bool
const
-correctness and const
-castsexplicit
and mutable
And so on. You do not, however, need to know what these features do to use their power.
It's nearly impossible to memorize the entire STL. It's not even necessary. Instead, it's helpful to know what's out there, and how to look things up when you need them.
A lot of the STL minimizes use of pointers and dynamic memory allocation, so the debugging time is greatly decreased.
Also, since everything is templated, a lot of the same algorithms can be used with multiple data structures!
Most STL implementations have the best possible big-O complexities, given their interface. There are two notable exceptions:
nth_element()
Miscellaneous:
vector<>
deque<>
bit_vector<> // same as vector<bool>
set<>
multi_set<>
map<>
multi_map<>
list<>
array<>
Linked list containers:
list<> // doubly linked, .size() in O(1)
slist<> // singly linked, .size() in O(n)
forward_list<> // singly linked, .size() does not exist
Do this.
#include <algorithm>
copy(vec.begin(), vec.end(), arr); // copy over
copy(arr, arr + SIZE, vec.begin()); // copy back
sort(arr, arr + SIZE);
sort(v.begin(), v.end());
Don't do this.
auto it = vec.begin();
int i = 0;
while (it != vec.end()) {
arr[i] = *it;
i++;
}
Or anything of the variety. Using builtins like sort()
and copy()
is a lot safer and in a more functional style.
Data structure | Memory overhead |
---|---|
vector<> |
Compact |
list<> |
Not very compact |
unordered_map<> |
Memory hog |
If memory is a worry, don't use an unordered_map<>
.
swap<>
and max<>
.void double_all(std::vector<int> & v) {
std::for_each(v.begin(), v.end(), [](int in) {in *= 2;});
}
Pretty nifty, right? There is also the function std::transform()
, which copies the lambda's return value to each element.
Let's say, however, that you want to sort a custom class. Instead of overloading the operator<()
, use a functional object as your comparison and then use standard library tools.
struct SortByName {
bool operator()(const Employee & left,
const Employee & right) const {
return left.getName() < right.getName();
}
};
You can then use it like so:
vector<Employee> people(100);
// fill them
SortByName nameSort();
sort(people.begin(), people.end(), nameSort);
This is a little tidbit which is great for testing your program.
srand(time(nullptr));
vector<int> perm(N);
// fill it up
for (unsigned int i = 0; i < N; i++) {
perm[i] = i;
}
random_shuffle(perm.begin(), perm.end());
You can also sort arrays by using:
random_shuffle(perm, perm + N);
iota()
)You can use the iota()
function instead of using a loop:
iota(vec.begin(), vec.end(), 0); // fills all elements with 0
Crashes can occur in STL code, but started by an error in your code and not the library. In GDB, you can use the where
or bt
commands to find the code that calls the STL and find what happens from there.
Most of the errors related to STL are use of user's dangling pointers or references going out of scope, but that the container still uses.