I have a given buffer of characters (maybe even the buffer backing an std::string, but never mind that). I want to print into that buffer using an std::ostream, i.e. I want to be able to write:
span<char> my_buffer = get_buffer();
auto my_os = /* magic */;
static_assert(
std::is_base_of<std::basic_ostream<char>,decltype(my_os)>::value,
"magic failed");
my_os << "hello" << ',' << 123 << '\0';
std::cout << my_buffer << '\n';
and get:
hello,123
on the standard output.
Note: C 11 if possible, and please mention the language standard you're using. (And yes, I know C 11 doesn't have spans.)
CodePudding user response:
(Thank @BoP and @T.C. for the two parts of this solution)
This can be done... if you're willing to use a deprecated C construct: std:ostrstream.
#include <strstream>
#include <iostream>
int main() {
const size_t n = 20;
char my_buffer[n];
std::ostrstream my_os(my_buffer, n);
my_os << "hello" << ',' << 123 << '\0';
std::cout << my_buffer << '\n';
}
Notes about this code:
- It works (GodBolt)
- It is valid C 98! ... of course I had to let go of
std::span,autotype inference etc. It's also valid C 11 and later standards. - This will construct an
std::strstreambuf, which is what anstd::ostrstreamuses directly, from your buffer of chars.
Unfortunately, with the deprecation of std::ostrstream, we were left with no fully-valid alternative up to, and including, C 20. You would need to implement a custom std::basic_streambuf, and assign it to an std::ostream. :-(
But in C 23 - you are luck! The standard library does offer exactly what you asked for: std::spanstream: A std::ostream backed by a span of char's which it is given at construction.
