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

Я понимаю мотивацию для использования станд :: 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 by const& вместо string_view для аргументов функции?

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

15

Решение

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

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

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

7

Другие решения

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

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

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


2

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

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

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

2

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

bool matches(std::string s)
{
make_upper_case(s);
return lib::test_if_matches(s);
}

В любом случае вам нужна изменяемая строка где-то, поэтому вы можете объявить ее как параметр функции. Если вы изменили его на std::string_viewи кто-то передает std::string функционировать matches() вы бы сначала преобразовали string в string_view а потом string_view в stringи, следовательно, выделяя дважды.

0
По вопросам рекламы [email protected]