[БЕЗ_ЗВУКА] Итак, мы уже неплохо
знакомы с итераторами, но давайте все-таки вспомним, где мы их встречали раньше.
Мы встречали их в алгоритмах, в алгоритмах: sort, count,
count_if, reverse, find_if вот уже увидели.
Мы встречали их в конструкторах контейнеров, в частности,
мы с помощью итераторов создавали множество по элементам вектора и вектор по
элементам множества.
Просто конструктор принимал begin и end.
Кроме того, мы недавно увидели метод find у множества из словаря,
который тоже возвращал итератор.
Наверное, логично предположить,
что у нас есть огромное количество разных методов у контейнеров и алгоритмов,
которые возвращают итераторы и что-то с ними интересное делают.
Мы не могли это рассмотреть в первом курсе,
потому что вы пока не знали итераторы,
теперь же мы можем рассматривать эти самые методы контейнеров.
Давайте начнем с методов контейнеров.
Рассмотрим снова вектор строк, вектор языков программирования,
найдем там, скажем, C++.
auto it = find( begin(langs),
end(langs), "C++").
Ну, у алгоритма find_if есть его аналог, более простой аналог — алгоритм find,
который просто принимает элемент, который надо найти.
Что же с ним можно делать?
Вот у нас есть итератор, который указывает на конкретную позицию в контейнере.
С этой позицией можно что-то делать.
Например, можно у вектора langs вызвать метод erase,
взять и удалить конкретный элемент по итератору.
Мы помним, что у множества и у словаря был метод erase,
который принимал ключ, который надо было удалить.
У вектора же нет быстрого поиска по ключу, но можно удалить элемент по итератору.
Давайте я вызову функцию PrintRange, ту самую нашу шаблонную функцию от вектора
и убежусь, что у меня C++ удалился.
Компилирую.
Компилирую.
Запускаю.
И вижу, что у меня остались все элементы вектора, кроме C++.
На самом деле с помощью erase можно удалить и больше всего.
Можно удалить не один элемент, а целый диапазон.
Например, все, начиная с C++ и до конца, до end(langs).
Покажем, что у нас удалится все, начиная с C++, и кажется, останется только Python.
Сейчас мы это увидим.
Да, действительно, в векторе остался один элемент.
Прекрасно.
А что, если мы одумались и теперь хотим вернуть C++ обратно в вектор?
Для этого надо использовать метод insert.
Метод insert принимает не просто элемент, который надо вставить,
потому что у вектора много мест, куда можно вставить,
а если мы хотим вставить в конец, мы используем pushback.
Он принимает итератор, куда мы хотим вставить.
Соответственно, если я напишу insert(begin(langs), "C++"),
я вставлю C++ в начало вектора.
Поскольку у меня после удаления там остался только Python,
у меня должен поулчиться вектор из двух элементов: сначала C++, потом Python.
Да, действительно, так и получилось.
А что если я передам в insert какой-то другой итератор?
Давайте разберемся, что будет происходить.
Вызов метода insert от итератора и конкретного значения вставляет это
значение в вектор прямо перед этим итератором.
Соответственно, если у нас итератор — это begin,
то мы вставим прямо перед ним, то есть в самое начало вектора.
Если будет insert от end, то мы вставим прямо перед end,
то есть в самый конец вектора, это будет аналог pushback.
Ну и в произвольном случае я вставлю перед конкретным итератором.
Заметьте: у меня в векторе пять элементов, но при этом шесть итераторов (мы это
видели до этого) и с другой стороны у меня шесть позиций вставки в этот вектор:
в самое начало, в самый конец или где-то между элементами.
Получается, что удобно было сделать именно так: вставлять перед итератором.
Что еще может...
как еще можно вызывать insert?
Мы уже видели на самом деле метод insert в первом курсе,
мы тогда вставляли в конец одного вектора содержимое другого вектора.
И действительно, в insert можно передать диапазон элементов.
Сначала итератор, куда вставлять, а потом диапазон элементов, который мы вставляем.
Или можно передать в insert количество элементов, сколько
раз мы хотим вставить и тот самый элемент, который мы хотим вставить столько раз.
Это второй пункт списка.
И наконец, можно передать в insert в фигурных скобках набор элементов,
который мы хотим вставить в какое-то конкретное место вектора.