[БЕЗ_ЗВУКА] Итак,
получается, что у нас есть много разных итераторов.
Во-первых, мы видели итераторы множества, в которые записывать ничего нельзя,
там remove_if мы не могли вызвать.
Во-вторых, сейчас мы увидели итераторы inserter и back_inserter, из которых
нельзя читать, у вас не получится из них ничего прочитать, потому что они только
push_back умеют делать и больше ничего, они не ссылаются на конкретные элементы.
Итераторы, более того, зависят от того контейнера, на который они ссылаются.
Давайте мы это увидим на примере вектора и множества, все-таки вектор и множество
устроены сильно по-разному, и итераторы у них тоже должны как-то отличаться,
кроме того, что мы в них не можем записывать.
Например, давайте код множества уберем и рассмотрим такую задачу.
Найти в моем векторе строк, векторе названия языков, язык,
который начинается с буквы C, и найти позицию этого элемента.
Мы умеем находить итератор с помощью find_if, find_if (begin (langs),
end (langs)) и лямбда-функция.
И find_if возвращал итератор на этот элемент.
Как нам найти по итератору позицию?
Логично было бы предположить, что это можно сделать,
потому что итератор указывает как раз на конкретную позицию контейнера.
Оказывается, для этого достаточно из итератора,
который мы получили, вычесть итератор начала диапазона.
Давайте я посмотрю, что у меня получится.
Запущу, увижу 1.
Действительно, у строки C++ в векторе позиция № 1.
Итак, итераторы вектора можно вычетать друг из друга.
Такое не пройдет с итераторами множества.
Давайте, я для примера что-нибудь совсем простое совсем создам.
Пустое множество целых чисел И попробую из end вычесть begin.
Что произойдет?
Вот у меня ничего не скомпилировалось.
В частности, у меня проблема в этом выражении end − begin.
В частности, если тут пролистать сообщение об ошибке, то видно будет,
что компилятор не смог найти оператор «минус» для этих итераторов.
Помните, что вы когда определяли свои типы данных, например, рациональные числа,
вы там переопределяли оператор «плюс», оператор «минус» могли переопределить.
То же самое для итераторов.
Для итераторов множеств оператор «минус» не переопределен,
потому что нельзя вычитать один итератор множества из другого.
Векторы элемента хранятся подряд, и вы легко можете просто вычесть один
итератор из другого и понять, какое между ними расстояние.
У множества итераторы указывают на какую-то структуру данных,
в которой это множество хранит элементы, поэтому вычесть один из другого нельзя.
Аналогично получается, итераторы вектора можно сравнивать друг с другом не только
на равно / не равно, но и на меньше / больше.
А для итераторов множеств такое выражение не скомпилируется.
И получается, что для множеств нельзя использовать такие выражения.
Но иногда возникает соблазн использовать одно конкретное запрещенное выражение
для итераторов множества.
Какое именно, о каком идет речь?
Смотрите, я взял множество целых чисел, 1, 6, 8, 9,
нашел в этом множестве auto it = s.
find (6).
Нашел конкретную 6 и хочу вывести все элементы, больше этого.
Как мне это сделать?
Если я выведу диапазон от it до end, то это будут все элементы,
больше либо равные этому.
Как мне этот элемент исключить из рассмотрения?
Я мог бы сделать ++it и потом вывести
PrintRange (it, end (s)).
Давайте я проверю, что у меня будет действительно 8 и 9.
Хотя нет...
У меня переменная it уже занята, давайте будет it2.
Выведу всё от it2 до end(s).
Компилируем, запускаем.
Вижу, что у меня 8 и 9.
Действительно, вот все элементы, больше 6.
Но часто такое в коде случается,
что нельзя просто эту переменную взять и изменить, то есть переменную it2.
Может быть, она константная, этот итератор константный и нельзя его менять.
Может быть, просто неудобно в данном месте его менять.
Очень хочется ++it2 не писать, а написать вот здесь it2 + 1.
Но такой код не скомпилируется,
даже 1 прибавить нельзя, видите, сколько у нас ошибок.
Потому что для множеств нельзя прибавлять число.
Видите, оператор «плюс» у нас отсутствует.
Поэтому есть специальная функция next,
которая помогает вам сделать из + 1 с помощью ++, не меняя саму переменную it2.
По сути, это аналог it2 + 1 для множества.
Проверяем, да, действительно работает.
И у функции next есть аналог — функция prev, которая за вас делает минус-минус,
не меняя исходную переменную, возвращает предыдущий итератор.