Приводит ли использование string_view к ненужной копии строки в этом сценарии? - PullRequest
3 голосов
/ 28 мая 2020

Я пытаюсь сделать так, чтобы мой класс принял строку во время построения. Я читал, что string_view был заменой const string&, поэтому, естественно, я написал такой конструктор. Это позволяет мне принимать строки c ++ и c.

Url::Url(boost::string_view raw_url)
    : url_(static_cast<std::string>(raw_url)) {

Проблема, которая может быть здесь, заключается в том, что при передаче rvalue вместо перемещения появляется ненужная копия. Есть ли решение создать другой конструктор, который принимает string&&? Какая здесь лучшая практика?

1 Ответ

4 голосов
/ 28 мая 2020

Примечание: я напишу ответ, учитывая std::string_view, но boost::string_view должен быть похожим.


Я читал, что string_view заменяет const string &

Полезно понять причину, по которой std::string_view был добавлен в первую очередь.

В чем проблема с const string&?

Это, безусловно, эффективно, если вы передаете объект std::string и ничего не получаете с std::string_view . Но предположим, что теперь вы передаете char*, содержащее большую строку. В этом случае будет создан временный объект std::string (и вся строка, на которую ссылается этот char*, будет скопирована), так что функция получит std::string. Вот тогда светится std::string_view. Если вы передадите char* или std::string (или что-нибудь, что может быть преобразовано в std::string_view) функции, принимающей std::string_view (по значению, нет необходимости принимать std::string_view по ссылке), тогда новый * Создаваемый объект 1030 * очень дешев, так как это всего лишь «представление», и он не копирует базовую строку.


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

Url::Url(std::string raw_url)
    : url_(std::move(raw_url)) {

Есть даже clang-tidy warning , чтобы сообщить вам об этом.

Преимущество в том, что если пользователь вашей функции передает lvalue вы делаете копию (она вам все равно нужна) и ход, но если они передают rvalue, то копии не будет, а будет только ход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...