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

182
14 июля 2018, 09:00

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

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

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

Answer 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(). А в этом и заключается проблема, т.е. это ничего не экономит.

Answer 2

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

Еще вариант - написать самодельный поток.

READ ALSO
Кастомизация консольного приложения в Linux

Кастомизация консольного приложения в Linux

Пишу консольное приложение в Linux, вот и возникло два вопроса

172
с++ и виртуальное наследование

с++ и виртуальное наследование

Необходимо создать базовый класс который будет иметь 4 наследникаВся проблема в том, что мне нужен базовый класс в одном экземпляре, так как...

283
MemoryPuzzle — простая игра в консоли [требует правки]

MemoryPuzzle — простая игра в консоли [требует правки]

Я тут сделал свою первую нормальную консольную игру на С++Это простая игра

184
Как работает sync?

Как работает sync?

Не могу понять как он работаетЕсть пример:

187