Что такое string_view?
string_view
была предложена особенность в рамках Основ библиотеки C++ TS ( N3921), добавленная в C++17
Насколько я понимаю, это тип, который представляет какую-то строковую "концепцию", которая является представлением любого типа контейнера, который может хранить что-то видимое в виде строки.
- Это правильно?
- Должен канонический
const std::string&
тип параметра становитсяstring_view
? - Есть ли еще один важный момент о
string_view
принимать во внимание?
2 ответа
Цель любого и всех видов предложений "ссылка на строку" и "ссылка на массив" состоит в том, чтобы избежать копирования данных, которые уже принадлежат где-то еще и для которых требуется только неизменяемое представление. string_view
речь идет об одном таком предложении; были более ранние string_ref
а также array_ref
, тоже.
Идея состоит в том, чтобы всегда хранить пару указателей на первый элемент и размер некоторого существующего массива данных или строки.
Такой класс дескриптора представления может передаваться дешево по значению и предлагать дешевые операции подстроки (которые могут быть реализованы в виде простых приращений указателя и корректировки размера).
Многие виды использования строк не требуют фактического владения строками, и рассматриваемая строка часто уже будет принадлежать кому-то еще. Таким образом, существует реальный потенциал для повышения эффективности за счет исключения ненужных копий (подумайте обо всех выделениях и исключениях, которые вы можете сохранить).
Исходные строки C страдали от проблемы, заключавшейся в том, что нулевой терминатор был частью строкового API, и поэтому вы не могли легко создавать подстроки без изменения базовой строки (а-ля strtok
). В C++ это легко решить, сохранив длину отдельно и поместив указатель и размер в один класс.
Одно серьезное препятствие и расхождение с философией стандартной библиотеки C++, о которой я могу подумать, заключается в том, что такие классы "ссылочного представления" имеют полностью отличную семантику владения от остальной части стандартной библиотеки. По сути, все остальное в стандартной библиотеке безусловно безопасно и правильно (если оно компилируется, это правильно). С такими классами ссылок это уже не так. Правильность вашей программы зависит от окружающего кода, который использует эти классы. Так что это сложнее проверить и научить.
(Обучаюсь в 2021 году)
Из Microsoft <string_view>:
Семейство специализаций шаблонов string_view обеспечивает эффективный способ передачи доступного только для чтения, защищенного от исключений и не принадлежащего владельцу дескриптора символьных данных любых строкоподобных объектов с первым элементом последовательности в нулевой позиции. (...)
Из блога команды Microsoft C++ std::string_view: The Duct Tape of String Types от 21 августа 2018 г. (получено 1 апреля 2021 г.):
string_view решает проблему «каждая платформа и библиотека имеет свой собственный строковый тип» для параметров. Он может привязываться к любой последовательности символов, поэтому вы можете просто написать свою функцию, принимающую строковое представление:
void f(wstring_view); // string_view that uses wchar_t's
и вызовите его, не заботясь о том, какой строковый тип использует вызывающий код (и > для пар аргументов (char*, length) просто добавьте {} вокруг них) (...)
(...)
Сегодня наиболее распространенным «наименьшим общим знаменателем», используемым для передачи строковых данных, является строка с завершающим нулем (или, как это называется в стандарте, последовательность символов с нулевым завершением). Это было с нами задолго до появления C++ и обеспечивало чистое взаимодействие на «плоском C». Однако char* и его вспомогательная библиотека связаны с кодом, который можно использовать, поскольку информация о длине является внутренним свойством данных и может быть изменена. Кроме того, нуль, используемый для ограничения длины, запрещает встроенные нули и приводит к тому, что одна из наиболее распространенных строковых операций, запрашивающая длину, становится линейной по длине строки.
(...)
Каждая область программирования создает свой собственный новый тип строки, семантику времени жизни и интерфейс, но многие программы обработки текста не заботятся об этом. Выделение полных копий данных для обработки только для того, чтобы удовлетворить различные типы строк, неоптимально с точки зрения производительности и надежности.