Without using a full-blown logging library (or IF statements) - is there a way in C++ to sometimes print out messages to the console and sometimes not?
I am using std::cerr, is there a way to control when this outputs or not?
Ideally I could have:
std::cerr << "Constructor called" << endl;
and have a way to enable/disable this line of code?
I am not sure what you mean by "without if", but you can write code without using the if yourself. A macro can check a flag for you.
#define CERR if (cerr_disabled) {} else std::cerr
bool cerr_disabled = false;
Then, in your code:
CERR << "error message" << std::endl;
If cerr_disabled is true, then nothing is printed.
The advantage of this macro approach is that none of the print arguments get evaluated if the err logging is disabled. For instance, if you needed to call a function to create a more complicated log string:
std::string fancy_log_message () {
//...
}
CERR << fancy_log_message();
If cerr_disabled is true, fancy_log_message() is not called. This is something that can't be achieved by just suppressing the stream object itself.
The simple approach is to set/clear std::ios_base::failbit on the stream: while std::ios_base::failbit is set, the streams won't do any work [unless the output operators are written incorrectly]:
std::cerr.setstate(std::ios_base::failbit);
std::cerr << "this won't show\n";
std::cerr.clear();
std::cerr << "this will show!\n";
To make these operations easier to use you can create manipulators, e.g.:
std::ostream& stream_on(std::ostream& out) {
out.clear();
return out;
}
std::ostream& stream_off(std::ostream& out) {
out.setstate(std::ios_base::failbit);
return out;
}
std::cerr << stream_off << "not printed\n" << stream_on << "printed\n";
If you really want to disable the stream even if the output operators are badly implemented, you can save the current rdbuf() (e.g., in a suitable std::ostream::pword()) and set the stream buffer to nullptr:
static int stream_off_index() { static int rc = std::ios_base::xalloc(); return rc; }
std::ostream& stream_on(std::ostream& out) {
out.pword(stream_off_index) = out.rdbuf(nullptr);
return out;
}
std::ostream& stream_off(std::ostream& out) {
if (!out.rdbuf()) {
out.rdbuf(out.pword(stream_off_index);
}
return out;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With