Когда я передам const & std::string вместо std:: string_view?

Я понимаю мотивацию использования std:: string_view;
это может помочь избежать ненужных распределений в аргументах функции.

Например:
Следующая программа создаст std::string из строкового литерала.
Это вызывает нежелательное динамическое распределение, так как нас интересует только наблюдение за символами.

#include <iostream>

void* operator new(std::size_t n)
{
    std::cout << "[allocating " << n << " bytes]\n";
    return malloc(n);
}

void observe_string(std::string const& str){}

int main(){
  observe_string("hello world"); //prints [allocating 36 bytes]
}

Использование string_view решит проблему:

#include <iostream>
#include <experimental/string_view>

void* operator new(std::size_t n)
{
    std::cout << "[allocating " << n << " bytes]\n";
    return malloc(n);
}

void observe_string(std::experimental::string_view const& str){
}

int main(){
  observe_string("hello world"); //prints nothing
}

Это оставляет мне вопрос.
Когда я выберу std::string функцией const & вместо string_view для аргументов функции?

Глядя на интерфейс std::string_view, похоже, что я могу заменить все экземпляры std::string, которые передаются const&. Есть ли какие-либо встречные примеры? Является ли std::string_view заменой std::string const& для передачи параметров?

Ответ 1

Когда я могу выбрать std::string вместо const& вместо string_view для аргументов функции?

Вам нужна строка с нулевым завершением? Если да, то вы должны использовать std::string const&, который дает вам эту гарантию. string_view нет - это просто диапазон const char.

Если вам не нужна строка с завершающим нулевым символом, и вам не нужно владеть данными, вы должны использовать string_view. Если вам нужно взять данные о себе, то может быть, что string по значению лучше, чем string_view.

Ответ 2

Андрей Александреску однажды сказал: "Нет работы лучше, чем какая-то работа". Поэтому вы должны использовать const std::string& в таких контекстах. Поскольку std::string_view все еще требует некоторой работы (копирование пары указателей и длины).

Конечно, ссылки на const могут по-прежнему иметь стоимость копирования указателя; что почти эквивалентно тому, что будет делать std::string_view. Но есть еще одна работа с std::string_view, она также копирует длину.

Это теоретически, но на практике критерий будет предпочтительным для определения производительности


Ответ 3

Одна из возможных причин принять const std::string& вместо string_view - это когда вы хотите сохранить ссылку на строковый объект, который может измениться позже.

Если вы принимаете и сохраняете string_view, это может стать недействительным, когда внутренний буфер string перераспределяется.

Если вы принимаете и храните ссылку на собственно строку, у вас не будет этой проблемы, если этот объект жив (вы, вероятно, захотите удалить опорную перегрузку r-значения, чтобы избежать очевидной проблемы с временными).