MoustacheSpy
MoustacheSpy

Reputation: 763

How can I make a condition within a macro without using a macro

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

Answers (1)

Jean-Baptiste Yun&#232;s
Jean-Baptiste Yun&#232;s

Reputation: 36401

#defines 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 #defines as you want to do nothing when console_verbose is false. #defines 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

Related Questions