# Iterators and Algorithms to Know
- Note that passing the name of a function into another function allows you to emulate the *higher order* feature of Functional Programming
```cpp=
int main() {
auto out_int[](int i){ cout << i << endl; }
for_each(..., ..., out_int);
// this is a valid operation
}
```
- These are called **function objects**
# Iterators
- Similar to array pointer arithmetic, iterators are a way to look at memory values in an array. Every container has an iterator defined with `C.begin()` (first element) and `C.end()` (pointing to just after the end of the container)
- Example:
```cpp=
vector<int> V = {1, 2, 3, 4, 5};
for(vector<int>::iterator p = V.begin(); p != V.end(); ++p) {
cout << *p << endl;
}
```
- Common Operations (Remember, all iterators are standardized)
- `operator*` - Element at current position (return dereference)
- `operator->` - Member Selection from current pos (return ptr)
- `operator++/--` - move to next/prev element
- `operator==` - compare for positional equality
- `operator=` - assign an iterator
- (most of these are seen above)
- Can be categorized into input, output, forward, bidirectional (list, set, multiset, map, multimap), random access (vector, deque, string), or contiguous (adjacemtn in memory -- array, string, vector) (Contiguity is C++17 onwards)
### Common Iterators for Convenience
- `istream_iterator<T>(obj)/ name(obj)` - no object provides default, this iterator lets you treat an input stream as an array of sorts
- `ostream_iterator<T>^^(see above)` - this iterator lets you treat an output stream as an array of sorts
- `istringstream` - simulates string input for `operator>>`
- `stringstream` - simulates a string as an input stream for output
# Algorithms
- C++ STL Algorithms are common ways to solve problems that have been written time and time again.
- Some of these include `copy`, `transform`, etc.
### Common Algorithms and Parameters to Know:
- `accumulate(begin, end, initial_value)` - Python `sum()`
- `sort(begin, end)` - Python `.sort()` -- List is the only stl container that has its own .sort() member
- `find(begin, end, element)` - Search Algo, returns iterator
- `find_if(begin, end, condition)` - Returns iterator to first element that satisfies the condition
- `transform(start_iter, end_iter, copy_iter, operation)` - transforms a set of values by mapping `operation` on top of them
- `copy(start, end, output)` - copies from start->end into output
- `for_each(start, end, func)` - applies `func` to each element between start and end
- if the function takes by reference, mutable access is possible in this manner
- `remove(start, end, ele)` and `remove_if(start, end, func)` - self-explanatory, though remove removes *all* occurences of the element provided
- `unique(start, end)` - removes all duplicates in the range
- `generate(start, end, function_that_returns_value)` - fill the container with the function
- Note that all parameters that aren't explicity some variation of "element/ele" represent a function object, usually a lambda, that you apply
**IMPORTANT NOTE ABOUT `remove`, `remove_if`, AND `unique`**: When applied, they move all the elements to remove to the back of the container. These functions then return iterators to the first element to remove. For example, for vectors:
```cpp=
std::vector<int> v {1, 2, 3, 4, 5, 5};
auto it = std::unique(v.start(), v.end());
v.erase(it, v.end()) // THIS IS WHAT ACTUALLY PERFORMS DELETION!!
```
## Ranges
- Ranges are used automatically in for-loops, but also abstract away the `C.start()/end()` syntax that has become very prevalent.
- `ranges::sort(v)` can replace `algorithms::sort(v.begin(), v.end())`
- they are a more unified way to write these types of repetitive algorithms
# Exceptions
- C++ STL Exceptions are common exceptions that you would encounter in languages like Java or Python (base class `Exception`)
- Imported from `<stdexcept>` and `exception` is the base class