Я понимаю мотивацию для использования станд :: 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&
для передачи параметров?
Когда бы я выбрал
std::string
отconst&
вместоstring_view
для аргументов функции?
Вы необходимость строка с нулевым символом в конце? Если так, то вы должны использовать std::string const&
что дает вам эту гарантию. string_view
нет — это просто ряд const char
,
если ты не делайте нужна строка с нулевым символом в конце, и вам не нужно вступать во владение данными, тогда вы должны использовать string_view
, Если вам нужно взять на себя ответственность за данные, то это может быть тот случай, когда string
по значению лучше чем string_view
,
Андрей Александреску однажды сказал: «Нет работы лучше, чем работа». Так что вы должны использовать const std::string&
в таких контекстах. Так как std::string_view
все еще включает в себя некоторую работу (копирование пары указателя и длины).
Конечно, ссылки на const могут все еще иметь стоимость копирования указателя; что почти эквивалентно тому, что std::string_view
Сделаю. Но есть еще одна работа с std::string_view
также копирует длину.
Это теоретически, но на практике предпочтение будет отдаваться тесту производительности
Одна из возможных причин принять const std::string&
вместо string_view
это когда вы хотите сохранить ссылку на строковый объект, который может измениться позже.
Если вы принимаете и храните string_view
, это может стать недействительным, когда string
внутренний буфер перераспределяет.
Если вы примете и сохраните ссылку на саму строку, у вас не будет этой проблемы, пока этот объект жив (вы, вероятно, захотите удалить перегрузку ссылки на r-значение, чтобы избежать очевидной проблемы с временными файлами).
Это не совсем то, что вы просили, но иногда вы хотите принять 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
и, следовательно, выделяя дважды.