2

Is there in C++ already some class which print to cout but can be off when some macro is not defined (for example DEBUG) ?

I can do like

#ifdef DEBUG
std::cout<<"some data"<<"new log<<"\n";
#endif

but is there already overridden operator<< so this be compressed on just one line

PaolaJ.
  • 10,872
  • 22
  • 73
  • 111
  • Generally if you do this you want the statement to be wrapped in a macro too, so that the parameters are not needlessly evaluated when the output is disabled. There's no way to do that with just an operator overload. – Mark Ransom Jan 10 '14 at 20:14
  • @MarkRansom The compiler will probably be able to optimize it away easily and im sure that a more advanced solution using constexpr and/or templates could also avoid it without macros – Sebastian Hoffmann Jan 10 '14 at 20:22

3 Answers3

4

You can easily make your own:

namespace mystd
{
   struct X {
       template<typename T>
       X& operator << (const T& x)
       {
       #ifdef DEBUG
           std::cout << x;
       #endif
           return *this;
       }
   } cout;
}

and write

mystd::cout << "   " << "   ";
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • will e.g. functions (`mystd::cout << "lala " << foo();`) be called if DEBUG is not defined? i'm not sure, but since shift operator precedence is left to right i would say yes. – user1810087 Jan 14 '14 at 12:28
  • @itwasntpete yes, but it's a no-op in this case. – Luchian Grigore Jan 14 '14 at 12:43
  • whops, my sence was totaly wrong :( sorry for that. i meant will it be called if DEBUG *is* defined and i asume not because of the precendence. :) – user1810087 Jan 14 '14 at 13:14
1

Simple answere: No, but you can implement this logic easily.

More advanced logging frameworks will actually define a bigger set of logging levels and decide to log based on the current level and the level of the message.

For an example you could take a look at the Poco framework: http://pocoproject.org/slides/110-Logging.pdf

They also offer an std::ostream wrapper around their logging framework

Sebastian Hoffmann
  • 11,127
  • 7
  • 49
  • 77
1

You could use std::ostream state flags to conditionally disable output. A corresponding use code look like this:

std::cout << log << "hello, ";
std::cout << "world\n";

The implementation which enables/disables output when using log could be something like the code below: log is actually constructing an objects which will disable the output if DEBUG is not defined when inserted into a stream by setting the stream flag std::ios_base::failbit. Its destructor will restore the stream state if the state got changed. Since a stream is used, you can also pass the stream object to a function and it will conditionally write output:

extern void f(std::ostream&);
f(std::cout << log);

Of course, the objects also work with other std::ostream objects, not just std::cout.

#ifndef SIMPLE_LOG
#define SIMPLE_LOG

#include <ostream>

class log_enabled
{
    mutable std::ostream*          stream;
    mutable std::ios_base::iostate state;
    bool                           logging;
public:
    log_enabled(bool l)
        : stream(0)
        , state()
        , logging(l) {
    }
    ~log_enabled() {
        if (stream) {
            stream->clear(this->state);
        }
    }
    std::ostream& setup(std::ostream& out) const {
        if (!logging) {
            this->stream = &out;
            this->state = out.rdstate();
            out.setstate(std::ios_base::failbit);
        }
        return out;
    }
};

std::ostream& operator<< (std::ostream& out, log_enabled const& log) {
    return log.setup(out);
}

#  ifdef DEBUG
#    define log log_enabled(true)
#  else
#    define log log_enabled(false)
#  endif

#endif
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • @itwasntpete: When `DEBUG` is defined, `log_enabled` hold a `logging` member which is `true`, i.e., the condition in `setup()` (i.e., `!logging`) is `false` and the output is not disabled. I think the logic is the correct way around (and that's also what the tests confirmed...). – Dietmar Kühl Jan 10 '14 at 21:39
  • ahh, ok i see. the word order was confusing me :) – user1810087 Jan 10 '14 at 23:16