I have a named std::string
that I want to fill with data via an std::ostream
interface and avoid a string copy.
One way to do it which does involve a copy is to do this:
bool f(std::string& out)
{
std::ostringstream ostr;
fillWithData(ostr);
out = ostr.str(); // 2 copies here
return true;
}
I need to pass the result through out
and cannot return ostr.str()
.
I want to avoid the copies in out = ostr.str();
since this string may be very big.
Is there some way, maybe using rdbuf()
s, to bind the std::ostream
buffer directly to out
?
To clarify, I am interested in the auto-expanding behaviour of std::string
and std::ostream
so that the caller does not have to know the size before the call.
UPDATE: I just realized that the innocuous line out = ostr.str();
will probably entail 2 copies:
str()
callstd::string
assignment operator.There is no second copy, because it's the move assignment.
Since C++20, std::ostringstream
provides a new member function that can consume itself and return std::string
:
std::basic_string<CharT,Traits,Allocator> str() &&;
Therefore, you may avoid the first copy in this way:
bool f(std::string& out)
{
std::ostringstream ostr;
fillWithData(ostr);
out = std::move(ostr).str();
return true;
}
https://en.cppreference.com/w/cpp/io/basic_ostringstream/str