Reputation: 763
I have a file named globals.h that looks like this:
#pragma once
#include <iostream>
#include <fstream>
#include <vector>
///Defines
//Developer tools
//IO
#define LOG if(console_verbose) if(!console_log_mode) std::cout else logfile
#define COUT std::cout
#define ENDL std::endl
#define VECTOR std::vector
//CLASS SHORTCUTS
#define CONSTR_END_GENERIC this->id = instanceCounter; instanceCounter++
#define DESTR_END_GENERIC instanceCounter--
///Namespace extensiont
namespace REBr
{
///Variables
extern constexpr bool console_verbose = true;
extern constexpr bool console_log_mode = false; ///false = log to console true = log to file
extern std::ofstream logfile("./logs/standard.log",ios::out);
};
I want the LOG macro to work like this:
If console_verbose is true, logging is enabled.
If console_log_mode is false, everything is being printed to the console (using cout)
If console_log_mode is true, everything is written to the logfile(using logfile)
I want to use it like this:
LOG<<"Some message"<<ENDL;
It works without the file check, which is logical. How can I get it to work with the file output option?
Upvotes: 1
Views: 94
Reputation: 36401
#define
s are mostly just syntactic replacement. Then something like LOG << "some message"
is replaced by if(console_verbose) if(!console_log_mode) std::cout else logfile << "some message"
which is syntactically wrong.
You can't solve your problem with #define
s as you want to do nothing when console_verbose
is false
. #define
s are generally considered as harmful in C++, so please don't dig more in this direction.
The solution would be to create a class (for example and as suggested in comments) with the overloaded operator <<
, which could be instanciated with your booleans, so that writing to it would make the right thing. Something like:
class LOG {
public:
LOG(bool verbosity, bool mode) {...}
template <typename T> LOG &operator<<(T v) {...}
};
Upvotes: 3