2

I wanted to use the approach given in this answer: https://stackoverflow.com/a/5419388/2050788, but apparently I'm missing something, as cout does not wind up being redirected. Can someone explain what I'm missing?

Here's a minimal compileable example:

#include <sstream>
#include <streambuf>
#include <iostream>

struct cout_redirect {
    cout_redirect( std::streambuf * new_buffer )
        : old( std::cout.rdbuf( new_buffer ) )
    { }

    ~cout_redirect( ) {
        std::cout.rdbuf( old );
    }

private:
    std::streambuf * old;
};

void no_guard() {
  std::cout << "No RAII" << std::endl;
  std::stringstream buffer;
  std::streambuf *old = std::cout.rdbuf(buffer.rdbuf());
  std::cout << "Bla" << std::endl;
  std::cout.rdbuf(old);
  std::cout << "Text = " << buffer.str() << std::endl;
}

void with_guard()
{
  std::cout << "Using RAII" << std::endl;
  std::stringstream buffer;
  cout_redirect(buffer.rdbuf());
  std::cout << "Bla";
}

int main() {
  no_guard();
  with_guard();
}

The output is:

 No RAII 
 Text = Bla

 Using RAII
 Bla

The No RAII case works as expected. In the RAII case, I would expect there to be no output, as cout should be redirected to the stringstream buffer. What am I missing? (compiled with g++ -Wall test.cpp using gcc 7.3.1).

EDIT: Ok, I was being really dumb -- but I'm big enough to admit it and leave this here as a reminder of my fallibility.

Spacemoose
  • 3,856
  • 1
  • 27
  • 48
  • 1
    Note also that you should probably delete copy constructor of `cout_redirect `. Rule of 3/5/0... – Jarod42 Mar 06 '18 at 15:34

2 Answers2

1

I think that cout_redirect(buffer.rdbuf()); just creates temporary object that is deleted on ;. Try cout_redirect cr(buffer.rdbuf());.

In practice it's nice to wrap such thing in macro to generate unique name automatically.

graywolf
  • 7,092
  • 7
  • 53
  • 77
0

cout_redirect(buffer.rdbuf()); constructs a temporary cout_redirect object, which redirects cout, then destroys the temporary object, which restores cout.

Did you mean cout_redirect guard(buffer.rdbuf()); instead?

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • @Spacemoose Side note: You could've reduced your test case much more by removing all cout redirection and just printing debug messages in your constructor/destructor. :-) – melpomene Mar 06 '18 at 15:29
  • yeah... what can I say. I'm having a bad day. – Spacemoose Mar 06 '18 at 15:31