#include <sstream>
#include <string>
using namespace std;
template<typename T>
string ToString(const T& obj)
{
ostringstream oss;
oss << obj;
//
// oss will never be used again, so I should
// MOVE its underlying string.
//
// However, below will COPY, rather than MOVE,
// oss' underlying string object!
//
return oss.str();
}
How to move std::ostringstream's underlying string object?
The standard says that std::ostringstream::str()
returns a copy.
One way to avoid this copy is to implement another std::streambuf
derived-class that exposes the string buffer directly. Boost.IOStreams makes this pretty trivial:
#include <boost/iostreams/stream_buffer.hpp>
#include <iostream>
#include <string>
namespace io = boost::iostreams;
struct StringSink
{
std::string string;
using char_type = char;
using category = io::sink_tag;
std::streamsize write(char const* s, std::streamsize n) {
string.append(s, n);
return n;
}
};
template<typename T>
std::string ToString(T const& obj) {
io::stream_buffer<StringSink> buffer{{}};
std::ostream stream(&buffer);
stream << obj;
stream.flush();
return std::move(buffer->string); // <--- Access the string buffer directly here and move it.
}
int main() {
std::cout << ToString(3.14) << '\n';
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With