Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to change ostringstream rdbuf?

I try the following code:

ostringstream oss;

streambuf *psbuf, *backup;

backup = oss.rdbuf();     
psbuf = cout.rdbuf();        
oss.rdbuf(psbuf);        
oss << things << endl;
oss.rdbuf(backup);   

But unfortunately I get this error:

error: too many arguments to function call, expected 0, have 1
    oss.rdbuf(backup);   

But rdbuf has two overloads:

get (1) basic_streambuf<char_type,traits_type>* rdbuf() const;

set (2) basic_streambuf<char_type,traits_type>* rdbuf (basic_streambuf<char_type,traits_type>* sb);

Yes I know it says basic_streambuf but it really is just a typedef typedef basic_streambuf<char> streambuf;, so it should work. Why is it not working?

like image 883
user3391320 Avatar asked Mar 07 '14 06:03

user3391320


1 Answers

Even though std::ostringstream inherits rdbuf from std::basic_ios that overload will not be accessible due to the fact that std::basic_ostream also defines its own member-function named rdbuf, effectively hiding the overload(s) you are looking for.

You can get access to the member-function by casting your std::ostringstream instance to a std::ostream reference as in the below example:

std::ostringstream oss;
std::ostream&      oss_ref = oss;

auto prev = oss_ref.rdbuf (std::cout.rdbuf ());

oss << "hello world"; // will print to the buffer of std::cout

oss_ref.rdbuf (prev); // reset

static_cast<std::ostream&> (oss).rdbuf (...) // equivalent

Why does std::basic_ostringstream define its own rdbuf?

Normally rdbuf returns a std::basic_streambuf* but std::ostringstream uses a std::basic_stringbuf.

Since one cannot overload based on return-type a decision was made to effectively hide the former overload in favour of the new one.

By returning a std::basic_stringbuf it's easy to see that std::ostringstream uses a stringbuf internally, and it also provides easier access to the str functions of std::basic_stringbuf (functions which doesn't exist in std::basic_streambuf).

like image 68
Filip Roséen - refp Avatar answered Oct 03 '22 01:10

Filip Roséen - refp