Что такое string_view?

162

string_viewбыла предложена особенность в рамках Основ библиотеки C ++ TS ( N3921 ), добавленная в C ++ 17

Насколько я понимаю, это тип, который представляет какую-то строковую «концепцию», которая представляет собой вид любого типа контейнера, который может хранить что-то видимое в виде строки.

  • Это правильно ?
  • Должен ли канонический const std::string&тип параметра стать string_view?
  • Есть ли еще один важный момент, string_viewкоторый стоит принять во внимание?
Drax
источник
4
Наконец, кто-то понимает, что строки нуждаются в другой семантике, хотя введение string_view - это только маленький шаг.
Джон З. Ли

Ответы:

183

Цель любого и всех видов предложений «ссылка на строку» и «ссылка на массив» состоит в том, чтобы избежать копирования данных, которые уже принадлежат где-то еще и для которых требуется только неизменяемое представление. Рассматриваемое string_viewявляется одним из таких предложений; были и те, что раньше назывались, string_refи array_refтоже.

Идея состоит в том, чтобы всегда хранить пару указателей на первый элемент и размер некоторого существующего массива данных или строки.

Такой класс дескриптора представления может передаваться дешево по значению и предлагать дешевые операции подстроки (которые могут быть реализованы в виде простых приращений указателя и корректировки размера).

Многие виды использования строк не требуют фактического владения строками, и рассматриваемая строка часто уже будет принадлежать кому-то другому. Таким образом, существует реальный потенциал для повышения эффективности за счет исключения ненужных копий (подумайте обо всех выделениях и исключениях, которые вы можете сохранить).

Исходные строки C страдали от проблемы, заключавшейся в том, что нулевой терминатор был частью строковых API, и поэтому вы не могли легко создавать подстроки без изменения базовой строки (а-ля strtok). В C ++ это легко решить, сохранив длину отдельно и поместив указатель и размер в один класс.

Одно серьезное препятствие и расхождение с философией стандартной библиотеки C ++, о которой я могу подумать, заключается в том, что такие классы «ссылочного представления» имеют полностью отличную семантику владения от остальной части стандартной библиотеки. По сути, все остальное в стандартной библиотеке безусловно безопасно и правильно (если оно компилируется, это правильно). С такими ссылочными классами это уже не так. Правильность вашей программы зависит от окружающего кода, который использует эти классы. Так что это сложнее проверить и научить.

Керрек С.Б.
источник
19
Корабль плыл по этой философии reference_wrapper, не так ли?
Стив Джессоп
5
@KerrekSB Боюсь, я не пойду. Не могли бы вы подробнее остановиться на части «такие классы ссылочного представления имеют семантику владения, совершенно отличную от остальной части стандартной библиотеки» , пожалуйста? Мне непонятно: чем это отличается от свисающих ссылок / указателей? Или недействительные итераторы из-за вставки (например, std :: vector)? У нас уже есть эти проблемы, для меня совершенно естественно, что у не-владеющего представления будут те же проблемы, что и у не-владеющих указателей / ссылок / итераторов.
Али
5
@ Али: Когда вы используете любой другой стандартный контейнер библиотеки, вы можете подтвердить правильность кода, просто взглянув на код, который использует контейнер. Не так для string_view. (Я не говорил, что вы никогда не сможете написать неработающий код. Просто то, что взлом является локальным .)
Kerrek SB
6
Я удивлен , что они не идут с std::rangeот boost::iterator_range- IMO это лучше , чем идея string_view
Чарльз Salvia
19
@nwp: Многие люди и языки стали оплакивать ужасные значения по умолчанию в C ++ и считают, что «const» и «unhared» должны быть по умолчанию, с «mutable» и «shared» явными, редкими исключениями.
Керрек С.Б.