адаптер - обёртка над методами нижележащего типа итератор - это такой тип, который позволяет делать обход последовательности его можно разыменовывать, инкрементировать и сравнивать на равенство обычный указатель формально тоже итератор
метатерминология итераторов:
- input iterator i1 != i2, *i, i->m, ++i, - для однопроходного алгоритма (ex. istream_iterator)
- forward iterator - i++, гарантирует, что если ходить по одной последовательности несколько раз, не меняя её, то мы будем видеть одно и тоже (ex. std::forward_list, std::unordered_map, std::unordered_set)
- bidirectional iterator - — (можно декрементировать) (ex. std::list, std::map, std::set)
- random access iterator - +=n, -=n, iter1-iter2, <=, >= (ex. std::deque)
- contiguous iterator (C++20) - гарантирует, что он эквивалентен указателю, непрерывный участок памяти. *(&*it +n) == *(it+n) - сложение итераторов это просто хождение по памяти на n шагов (ex. std::vector, std::array, T*)
for (int x : s) {} - range-based for (C++11) - синтаксический сахар для обхода с помощью итератора
for (std::set<int>::iterator it = s.begin(); it != s.end(); ++it)
чтобы в контейнере работал range-based for, нужно определить итератор и методы .begin() и .end()
нужно использовать std::iterator_traits для итераторов вместо type_traits
как бы могло быть с концептами:

std::prev(), std::next() возвращают следующее и предыдущее значения итератора
template< class BidirIt > constexpr
BidirIt prev(BidirItit, typename std::iterator_traits<BidirIt>::difference_type n = 1 );
const_iterator - внутренний класс контейнеров, указатель на константу reverse_iterator - адаптер над итератором, разворачивает действия в обратную сторону
output_iterator - это такой итератор, который гарантирует корректность при записывании в него (т.е. что его можно его разыменовывать, инкрементировать, присваивать)
back_insert_iterator - адаптер над итератором - output iterator - реализован так, что будто бы записываем в контейнер

- insert_iterator
потоковые итераторы
std::istream_iterator/std::ostream_iterator - можно завести на поток ввода/вывода (cin, cout)
std::istream_iterator<int> it(std::cin);
for (int i = 0; i < 5; ++i) {
v.push_back(*it);
}
делает вид, что происходит инкремент итератора, а на самом деле происходит ввод в поток
input, но не forward iterator
нету постфиксного инкремента, тк это не forward iterator
std::optional<T> - хранит либо T, либо ничего
хранит массив чаров sizeof(T) и bool. хранит на стеке
юзать std::optional - ещё один способ избежать std::exception
struct nullopt_t {};
nullopt_t nullopt;
есть std::nullopt - чтобы явно проинициализировать std::optional пустым значением
std::copy(it, std::istream_iterator<int>(), v.begin()); - считывание из потока и записывание в вектор
std::copy_n(it, 10, v.begin()); - считывание n элементов из потока и записывание в вектор в <algorithm>
std::copy(it, std::istream_iterator<int>(), std::back_inserter(v)); - считывание из потока в вектор, пока поток не закончился
std::vector<int> v(it, std::istream_iterator<int>());- конструктор вектора от считывания в поток
считать из файла в cout
std::ostream_iterator<int>(std::cout, " "); - через пробел
вывести в cout только чётные числа
лямбда функция - функция, которая вычисляется прям на месте
аналог:

вывести в cout квадраты чисел из файла
std::ostream_iterator реализован почти как std::back_inserter: при инкременте и разыменовании ничего не происходит, а при присваивании происходит вывод в поток
манипуляторы над потоками
std::cout << std::hex - объект, который будучи выведенным в cout меняет его стейт и после этого cout начинает выводить числа в 16ричном формате
set::presition - уточнить, с каким кол-вом цифр после запятой выводить double
std::boolalpha - true/false для bool
std::cin >> std::noskipws; - можно вводить пробелы (влияет только на ввод чаров!)
std::noskipws пофакту функция. то есть когда вводим кастуется к адресу на функцию. и cin видя это вызывает эту функцию от себя.
то есть это функция, которая сама вызывается от cin. возвращается ссылка на cin с поменяным стейтом
манипулятор потока - это функция. поток вызывает эту функцию на себя и возвращает ссылку на поток с поменяным стейтом

move_iterator - адаптер над итератором, который ведёт себя как нижележащий итератор, но его разыменование даёт rvalue&&, а не lvalue& применимость: мувнуть диапазон ограниченный мув итераторами в контейнер