Введение
Я пишу какое-то приложение для связи. До C++17 (без Boost) я использовал std::string
и его константную ссылку как cls1
.
Начиная с C++17, я представил std::string_view
в своем коде как cls2
. Однако у меня нет четкой политики, когда я должен использовать std::string_view
. Мое коммуникационное приложение получает данные из сети и сохраняет их в recv_buffer
. И создает некоторые классы приложений из recv_buffer
.
Строительство
Если я сосредоточусь только на конструкторе cls1
, конструкция перемещения будет эффективной. Но думаю, что откуда параметр s
. Если это исходно из recv_buffer
, я могу создать std::string_view
в приемной (очень ранней) точке. И пока recv_buffer
включен, используйте std::string_view
везде. Если мне нужно сохранить часть recv_buffer
, создайте std::string
.
Единственным исключением, которое я заметил, является то, что recv_buffer
всегда содержит полные данные для моего класса приложения. В этом случае эффективна конструкция перемещения.
Добытчик
Я думаю, что использование возвращаемого типа как std::string_view
имеет преимущество. Некоторые функции-члены, такие как substr()
, эффективны. Но недостатков пока не вижу.
Вопрос
Подозреваю, что могу увидеть только плюсы std::string_view
. Прежде чем переписывать много кодов, я хотел бы узнать ваши идеи.
PoC-код
#include <string>
struct cls1 {
explicit cls1(std::string s):s_(std::move(s)) {}
std::string const& get() const { return s_; }
private:
std::string s_;
};
struct cls2 {
explicit cls2(std::string_view s):s_(s) {}
std::string_view get() const { return s_; }
private:
std::string s_;
};
#include <iostream>
int main() {
// If all of the receive buffer is the target
{
std::string recv_buffer = "ABC";
cls1 c1(std::move(recv_buffer)); // move construct
std::cout << c1.get().substr(1, 2) << std::endl; // create new string
}
{
std::string recv_buffer = "ABC";
cls2 c2(recv_buffer); // copy happend
std::cout << c2.get().substr(1, 2) << std::endl; // doesn't create new string
}
// If a part of the receive buffer is the target
{
std::string recv_buffer = "<<<ABC>>>";
cls1 c1(recv_buffer.substr(3, 3)); // copy happend and move construct
std::cout << c1.get().substr(1, 2) << std::endl; // create new string
}
{
std::string recv_buffer = "<<<ABC>>>";
std::string_view ref = recv_buffer;
cls2 c2(ref.substr(3, 3)); // string create from the part of buffer directly
std::cout << c2.get().substr(1, 2) << std::endl; // doesn't create new string
}
}
Запуск демонстрации: https://wandbox.org/permlink/TW8w3je3q3D46cjk
std::string_view
отсутствуют все методы-модификаторы, которые есть вstd::string
(которые вам не нужны при работе с const ref),std::string::c_str()
также. - person YSC   schedule 18.06.2019