How to efficiently (with std::move()
if you like) construct a std::stringstream
from a std::string
, std::string_view
, or C-string in C++11 or later
Quick summary
std::string str("Hello "); // std::string
constexpr char c_str[] = "Hey and how are you "; // C-string
std::string_view sv(c_str); // std::string_view
std::stringstream ss1(str); // from a std::string
std::stringstream ss3(std::move(std::string(c_str))); // from a C-string
std::stringstream ss2(std::move(std::string(sv))); // from a std::string_view
Details
I just updated the accepted answer by @Nicol Bolas with the C++20 move-constructor (constructor #6) definition and explanation from https://en.cppreference.com/w/cpp/io/basic_stringstream/basic_stringstream. If you're using C++11, however, you can still get this efficiency boost (as far as I can tell) simply by calling std::move()
yourself.
With or without explicitly calling std::move()
, all 3 techniques below work to construct a std::stringstream
since C++11. So, having an extra constructor from std::string_view
really isn't necessary, since you can already construct a std::stringstream
from a std::string
, from a std::string_view
, or from a C-string (char
array), as shown below.
You can play with some test examples like these in my stringstream_initialize_from_std_string__string_view__and_c_string.cpp file in my eRCaGuy_hello_world repo.
std::string str("Hello "); // std::string
constexpr char c_str[] = "Hey and how are you "; // C-string
std::string_view sv(c_str); // std::string_view
// 1. Construct a `std::stringstream` from a `std::string`. This is
// constructor #3 from the link below: reference page for the
// `std::stringstream` constructors:
// https://en.cppreference.com/w/cpp/io/basic_stringstream/basic_stringstream
// - Open in mode `std::ios_base::app` as well in order to **append** all new
// writes to the end of the stream! See link above **and**:
// https://mcmap.net/q/717353/-how-to-append-content-to-stringstream-type-object
std::stringstream ss1(str,
std::ios_base::in | std::ios_base::out | std::ios_base::app);
ss1 << "world.\n"; // since `std::ios_base::app` was used above, this
// **appends** rather than **overwrites** the data in
// the stringstream.
std::cout << ss1.str() << "\n";
// 2. Construct a `std::stringstream` from a `std::string_view`. This is also
// constructor #3 from the link above (passing in a `std::string), but we must
// first construct a `std::string` from the `std::string_view`. We are using
// constructor #10 from the `std::string` constructors shown here to create a
// `std::string` from a `std::string_view`:
// https://en.cppreference.com/w/cpp/string/basic_string/basic_string
// - See also the note about the `std::ios_base::app` mode above.
std::stringstream ss2b(std::move(std::string(sv)),
std::ios_base::in | std::ios_base::out | std::ios_base::app);
ss2b << "today?\n";
std::cout << ss2b.str() << "\n";
// 3. Construct a `std::stringstream` from a C-string. This is also
// constructor #3 from the link above (passing in a `std::string), but we must
// first construct a `std::string` from the C-string. We are using
// constructor #5 from the `std::string` constructors shown here to create a
// `std::string` from a C-string (`const char*`):
// https://en.cppreference.com/w/cpp/string/basic_string/basic_string
// - See also the note about the `std::ios_base::app` mode above. Note that the
// C-string is used to automatically, implicitly construct a `std::string`
// here, I believe.
//
// implicit construction of `std::string` from `c_str`
std::stringstream ss3c(std::move(c_str),
std::ios_base::in | std::ios_base::out | std::ios_base::app);
ss3c << "doing?\n";
std::cout << ss3c.str();
// explicit construction of `std::string` from `c_str`
std::stringstream ss3d(std::move(std::string(c_str)),
std::ios_base::in | std::ios_base::out | std::ios_base::app);
ss3d << "doing?\n";
std::cout << ss3d.str();
Sample output:
Hello world.
Hey and how are you today?
Hey and how are you doing?
Hey and how are you doing?
References
std::stringstream
constructors: https://en.cppreference.com/w/cpp/io/basic_stringstream/basic_stringstream
- constructor #10 from the
std::string
constructors shown here to create a std::string
from a std::string_view
: https://en.cppreference.com/w/cpp/string/basic_string/basic_string
- and constructor #5 from the
std::string
constructors shown here to create a std::string
from a C-string (const char*
)
- How to append content to stringstream type object?