Почему не существует "std :: stringstream :: stringstream (std :: string &&)"? - программирование
Подтвердить что ты не робот

Почему не существует "std :: stringstream :: stringstream (std :: string &&)"?

Я надеялся, что stringstream имеет конструктор, который крадет исходное содержимое из string&&. Существуют ли такие межвидовые "движущиеся конструкторы" вообще не существуют в STL? Если нет, почему бы и нет?

4b9b3361

Ответ 1

Там история, которая разочаровывает. Но и будущее, которое выглядит ярким.

Когда семантика перемещения перешла на С++ 11, она была огромной, противоречивой и подавляющей. Я хотел иметь возможность перемещать строки в stringstream и из stringstream. Однако политика в то время требовала, чтобы внутренний магазин не должен был быть basic_string<charT>. Например, внутренним хранилищем может быть vector. И не было возможности контролировать вещи с помощью распределителя. В любом случае потребность была признана в С++ 11, но это был просто мост слишком далеко.

К счастью, Питер Соммерлад поднял слабину с P0408. Это предложение добавляет функции, которые вы ищете, надеюсь, для С++ 20, но это пока не определено. Он успешно прошел через LEWG и сейчас находится на LWG-столе. Они не добрались до этого в этом месяце в Рапперсвиле, просто из-за перегруженного графика. Я надеюсь, что он пройдет через LWG, и весь комитет будет голосовать. Это, безусловно, будет иметь мой голос.

Ответ 2

Почему не существует std::stringstream::stringstream(std::string&&)?

Это связано с внутренним буфером std::stringstream, rdbuf.

rdbuf, (тип std::string_buf), не поддерживает доступ без копирования в соответствии с мотивацией в предложении, p0408r4:

... не существует никакого копировального доступа к внутреннему буферу basic_stringbuf который делает по крайней мере получение выходных результатов из ostringstream неэффективным, поскольку копия всегда выполняется

Однако уже существует план поддержки std::string move в конструкторе stringsteam:

explicit basic_ostringstream(
   basic_string<charT, traits, Allocator>&& str,
   ios_base::openmode which = ios_base::out,
   const Allocator& a = Allocator());

И переместите str()

template<class SAlloc = Allocator>
void str(basic_string<charT, traits, SAlloc>&& s);