I have a std::stringstream ss
and a std::vector<string> list
.
I want to push_back
(or emplace_back
) ss
onto list
.
How do I do this in a way that best avoids making extra copies of ss
's backing string?
My intention is to immediately run ss.clear()
as I'll be re-filling it anew (to append to list
at a later time...)
Possible options:
list.emplace_back(std::move(ss.str())
list.emplace_back(ss.str())
list.push_back(std::move(ss.str())
list.push_back(ss.str())
What happens in each case? What will remain in ss
in each case? (I'll be throwing it away in any case)
Contributing to my uncertainty about what to do is this topic. The thing is, though, I'm not moving stringstreams into one another, I'm specifically only worried at this point in time about being able to move the string built as a stringstream (which might be huge) into the back of a container of strings. Obviously if str()
is implemented in such a way that causes some copy or conversion, that's just unavoidable, but hopefully I would like to generate code that will be able to just stuff it into the back of my vector in constant time.
I looked at the implementation of str()
:
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>
basic_stringbuf<_CharT, _Traits, _Allocator>::str() const
{
if (__mode_ & ios_base::out)
{
if (__hm_ < this->pptr())
__hm_ = this->pptr();
return string_type(this->pbase(), __hm_, __str_.get_allocator());
}
else if (__mode_ & ios_base::in)
return string_type(this->eback(), this->egptr(), __str_.get_allocator());
return string_type(__str_.get_allocator());
}
and was further confused.