Standard Template Library
Objectives
- Architecture
-
Architecture
C/C++ types are poor, and are mostly just a thin layer on top of the memory representation. This problem is especially acute with arrays and other data structures.
STL is a library providing both containers (such as vector) as well as algorithms, by means of the C++ templates with its main concern being performance and correctness.
Using templates solves the problem of implementing an algorithm for each of the possible types (Including user defined types)
But, The main STL challenge was the MxN problem ,with N containers and M algorithms.
Architecture - cont
How to avoid coding algorithms for each of the containers ?
Inheritance has 2 problems
- Inheriting from some base container has run time + space costs
- Although containers have overlapping behaviour it's not 100% compatible.
The solution that was chosen to avoid having to code algorithms for each of the containers is to entirely decouple the two and add another layer of abstraction in between
Containers
Algorithms
Iterators
Functors
Iterators
Iterators are pointer like abstraction to an element within a container
int arr[] = {1,2,3};
int* pI = &arr[0];
*pI = 10; // sets the first element of arr to 10
++pI; // Advance pI to next element
vector<int> v {1,2,3};
vector<int>::iterator itr = v.begin();
*itr = 10; // sets the first element of v to 10
++itr; // Advance itr to next element
Similar semantics for Iterators
begin()
end()
1
3
2
Container
Iterators - cont
In fact arrays and containers can be used interchangeably
int arr[] = {1,2,3};
for(int* p = &arr[0]; p != &arr[0] + 3; ++p)
cout << *p <<endl;
for_each(&arr[0], &arr[0] + 3, [](int n) { cout << n << endl; } );
vector<int> v {11,22,33};
for(vector<int>::iterator itr = v.begin(); itr != v.end(); ++itr)
cout << *itr << endl;
for_each(v.begin(), v.end(), [](int n) { cout << n << endl; } );
Iterators categories
there are 5 Iterators categories identifying the operations they support
- Input iterator: Only forward and one-pass, and only read
- Output iterator: Only forward and one-pass, and only write
- Forward iterator: Only forward, and read/write
- Bidirectional iterator: Forward and backward, and read/write
- Random access iterator: Arbitrary steps forward and backward in one breath, and read/write
Each iterator from the second group supports all the functionality in iterators mentioned before it.
C Pointer is considered a Random access iterator because it support all the operations a random access iterator dictates.
Containers
There are 2 types of containers
- Sequence
- array
- vector
- deque - double ended queue (FIFO/LIFO)
- list
- stack (LIFO)
- forward_list
- Associative
- map
- multimap
- set
- Multiset
- unordered_map
- unordered_multimap
- unordered_set
- unordered_multiset
Sequence containers
The user controls the order of the elements.
The vector<> is by far the most useful, and a replacement to the C array.
array, vector and deque all support fast random access to the elements. list supports bidirectional iteration, whereas forward_list supports only unidirectional iteration.
array does not support element insertion or removal.
vector supports fast element insertion or removal at the end. Any insertion or removal of an element not at the end of the vector needs elements between the insertion position and the end of the vector to be copied
Vector: Add - O(1) remove - O(N^2) Random Access - O(1)
Associative containers
The order of the containers is dictated by the values.
- map, multimap, set, multiset - Implemented using Binary tree
- unordered family are implemented using Hash
The first group requires the less than operator to be implemented, and is applying a strict weak ordering
The second requires a good hash function + Equality predicate
Map
Maps element are pair<T1,T2> ordering is performed on T1
multimap, set, multiset do not have operator[]
Algorithms
include <algorithm>
Possible division:
- Non-modifing (i.e count, find)
- Equal - test equality of interval
- all_of, any_of, none_of
- Mutating (i.e replace, transform)
- copy
- Sorting operations or variations (binary sort)
- binary_search - returns bool, std::lower_bound vs std::upper_bound vs equal_range
- stable_sort vs sort
- partial_sort
- nth_element
- minmax_element
Range insertion over back_inserter
STL
By perplexedpigmy
STL
- 1,201