Страницы

Поиск по вопросам

среда, 22 января 2020 г.

Забрать move семантикой строку из stringstream

#cpp


Чтобы сформировать строку использую std::stringstream
(набиваю содержимым оператором <<), затем выбираю полученную строку методом 
std::stringstream::str:

std::stringstream ss;
ss << "foo" << 42 << "bar";
std::string s = ss.str();


Исходный объект std::stringstream далее не используется, но при этом занимает память.
Есть ли возможность использовать move-семантику, чтобы "забрать" у  std::stringstream
его строку (в примере несущественно, в реальной задаче сейчас набивается строка в несколько
сот мегабайт)?
    


Ответы

Ответ 1



Внешняя спецификация класса std::strinstream никак не утверждает, что внутри объекта std::strinstream хранится "готовый к употреблению" объект std::string. Поэтому не приходится ожидать, что вам удастся "забрать" содержимое std::strinstream в std::string при помощи move semantics. То есть в общем случае избавиться от этапа построения объекта std::string на основе текущего содержимого std::strinstream не получится. Метод std::strinstream::str() возвращает свой результат по значению. Если при реализации этого метода компилятор применит оптимизацию возвращаемого значения (RVO), то результат ss.str() будет сконструирован прямо в вашем объекте s. В противном случае будет сконструирован и возвращен временный объект типа std::string, который вы уже заберете в свой s при помощи move semantics. Это, наверное, единственное место, где тут может сработать move semantics. P.S. В свете вышесказанного ясно, что не получится ничего достичь, работая с ss.str() "напрямую". Для этого все равно придется конструировать результат ss.str(). А в этом и заключается проблема, т.е. это ничего не экономит.

Ответ 2



Были еще старые строковые потоки не stringstream а strstream. Если мне не изменяет память, то у них после применения str() внутри замораживалась строка, и пользователю отдавался указатель на замороженную строку в виде char*. Если применить эти потоки, то лишнего копирования не будет. Правда они вроде-бы объявлены устаревшими. Еще вариант - написать самодельный поток.

Комментариев нет:

Отправить комментарий