[БЕЗ_ЗВУКА] В прошлом видео мы познакомились с классом StringView и написали с помощью него более эффективный код функции разбиения на слова. Давайте сделаем его ещё и более компактным. Итак, снова посмотрим на этот код. Мы здесь поддерживали текущую позицию в нашем StringView и двигали её по нему. Давайте мы от этой переменной избавимся и вместо того, чтобы держать единый string_view и по нему ходить позицией, я буду начала string_view двигать, как только я обработал уже первые сколько-то слов. То есть ещё раз. Я сейчас напишу такой код, который будет поддерживать следующий инвариант: если я какое-то начало string_view уже обработал, я его начала как бы подвину. И у меня в каждый текущий момент мой string_view str — вот он называется str — будет указывать на диапазон ещё не обработанных символов. И код получится компактнее. Давайте я продемонстрирую это в коде, а затем покажу на слайдах, что же там, на самом деле, происходит. Итак, у меня вектор остаётся на месте, а вот эти переменные я стираю. Если я говорю, что у меня string_view указывает на ещё не обработанные символы, тогда я могу просто искать первый пробел в ещё не обработанной части. Дальше я хочу взять подстроку, получается, от нулевой позиции. Но здесь есть приятный момент. Если я хочу взять подстроку от нулевой позиции до какой-то другой, и, возможно, эта какая-то другая позиция — в данном случае — space — может не существовать, то есть я что-то поискал, а оно не нашлось, тогда я могу просто использовать метод substr прямо вот так. Взять подстроку от нуля до space. Вот в этом случае всё будет ровно как надо. Я возьму подстроку до пробела. Если пробел нашёлся, тогда space — это его позиция, а также расстояние до него, то есть длина моего слова. А если пробел не нашёлся, тогда я вызову substr от нуля и end pos — и это будет вся строка оставшаяся. То есть вот здесь мы код сократили, а здесь я всё так же заканчиваю цикл. Если пробел не нашёлся, если его позиция — end pos, то надо закончить цикл, иначе нужно откусить от начала string_view уже обработанный кусок длины space плюс один с помощью специального метода remove_prefix. Указываю длину префикса, которую нужно откусить. Давайте я проверю, что этот код также работает и также эффективен. Компилируется. Да, скомпилировался, работает столько же, работает правильно. Отлично! Давайте разберём на слайдах, что же там происходит. Итак, вот этот самый код. Представьте, что у нас на входе была строка two words с одним пробелом посередине. Как же этот код будет работать? Мы заходим в цикл, ищем пробел, пробел находится, его позиция равна трём. Дальше я беру вызываю метод substr от параметров 0, 3. То есть я хочу подстроку, которая начинается с нулевой позиции и имеет длину три, это как раз первое слово. Вот оно добавилось у меня в вектор result. После этого я смотрю, не пора ли закончить цикл и откусываю префикс длины в данном случае четыре. space равно трём, space плюс один равно четырём. Я откусываю префикс длины четыре и по сути я всего лишь внутри string_view двигаю указатель. Было так, стало так. Я просто подвинул начало string_view, ничего никуда не копировал. Подвинул начала string_view. Я вместо переменной pos, с которой я итерировался по string_view, я использую сам внутренний указатель string_view, откусывая уже обработанный кусок. Дальше я перехожу на вторую итерацию цикла, ищу пробел, не нахожу. Теперь этот пробел, его просто нет, и space равно end pos. Я вызываю substr от нуля и от end pos и тем самым добавляю к ответу весь текущий string_view. Просто потому что я знаю, что это всё целиковое слово, пробелов в нём не осталось. Я могу весь текущий string_view str добавить к результату. Всё, и теперь я вижу, что у меня пробел равен end pos и можно закончить. Вот такой вот интересный паттерн — итерирование по string_view. Довольно удобно, на самом деле, и компактно. Цикл закончился. Итак, string_view — это некоторый аналог строки, но позволяющий сослаться на диапазон символов, не владея им при этом. По сути это просто указатель и длина или два указателя. При этом заодно мы узнали, что и у строки, и у string_view есть специальные методы, более удобные, чем стандартные функции, работающие с операторами, и эти методы работают с позициями. При этом есть специальная позиция end pos, некоторый аналог итератора, указывающего за конец. И мы показали, как итерироваться по string_view, откусывая от него префикс с помощью метода remove_prefix, у которого, кстати, есть аналог, откусывающий суффикс, называется remove_suffix.