我有一个用C ++编写的日志系统,用这种类型的函数写在它上面:
void processMessages();
void DEBUG_MSG(const std::string& appender,const char* msg, ...);
void INFO_MSG(const std::string& appender,const char* msg, ...);
void WARNING_MSG(const std::string& appender, const char* msg, ...);
void ERROR_MSG(const std::string& appender, const char* msg, ...);
void FATAL_MSG(const std::string& appender, const char* msg, ...);
我想在C ++中禁用宏。 我读过这个帖子:Disable functions using MACROS但是
#ifdef GLOG_SILENCE
#define processMessages (void)sizeof
#define DEBUG_MSG (void)sizeof
#define INFO_MSG (void)sizeof
#define WARNING_MSG (void)sizeof
#define ERROR_MSG (void)sizeof
#define FATAL_MSG (void)sizeof
#else //GLOG_SILENCE
void processMessages();
void DEBUG_MSG(const std::string& appender,const char* msg, ...);
void INFO_MSG(const std::string& appender,const char* msg, ...);
void WARNING_MSG(const std::string& appender, const char* msg, ...);
void ERROR_MSG(const std::string& appender, const char* msg, ...);
void FATAL_MSG(const std::string& appender, const char* msg, ...);
#endif //GLOG_SILENCE
无效。我不断收到错误:
包含在../ src / test_core.cpp:2:
中的文件中../src/test_Log.h: In member function ‘virtual void LogTestFixtureTest_defining_SILENCE_macro_avoids_write_and_processing_activity_from_log_Test::TestBody()’: ../src/test_Log.h:63: error: expected unqualified-id before ‘(’ token ../src/test_Log.h:63: error: expected primary-expression before ‘void’ ../src/test_Log.h:63: error: expected ‘;’ before ‘sizeof’ ../src/test_Log.h:64: error: expected unqualified-id before ‘(’ token ../src/test_Log.h:64: error: expected primary-expression before ‘void’ ../src/test_Log.h:64: error: expected ‘;’ before ‘sizeof’
我怀疑这个问题与Log是一个类有关,但我不知道该怎么做。 一些帮助?
答案 0 :(得分:4)
实际上,如果这些是成员函数,那么“无声”版本将扩展为无意义:
log.(void)sizeof(stuff);
您可以定义一个不执行任何操作的成员函数,以及吞下其参数的宏:
void nothing() {}
#define processMessages(...) nothing()
然后使用“无声”版本将提供有效的代码,这些代码应该编译为空:
log.nothing();
这样做的缺点是(a)你依靠编译器内联空函数,而不是生成函数调用; (b)在静默模式下编译时不会检查参数的语法。
答案 1 :(得分:0)
如果您的编译器支持variadic macros,您可以简单地定义具有空替换的宏:
#ifdef GLOG_SILENCE
#define processMessages(_1, _2, ...)
#define DEBUG_MSG(_1, _2, ...)
#define INFO_MSG(_1, _2, ...)
#define WARNING_MSG(_1, _2, ...)
#define ERROR_MSG(_1, _2, ...)
#define FATAL_MSG(_1, _2, ...)
#else //GLOG_SILENCE
void processMessages();
void DEBUG_MSG(const std::string& appender,const char* msg, ...);
void INFO_MSG(const std::string& appender,const char* msg, ...);
void WARNING_MSG(const std::string& appender, const char* msg, ...);
void ERROR_MSG(const std::string& appender, const char* msg, ...);
void FATAL_MSG(const std::string& appender, const char* msg, ...);
#endif //GLOG_SILENCE
但是,只有当函数是 NOT 类或命名空间的成员,而是真正的全局函数时,这才有效。
答案 2 :(得分:0)
我建议你以不同的方式工作。只需声明接口ILogger,然后在不同的记录器中实现它,如
class ILogger{
public:
virtual void DEBUG_MSG(const std::string& appender,const char* msg, ...);
virtual void INFO_MSG(const std::string& appender,const char* msg, ...);
virtual void WARNING_MSG(const std::string& appender, const char* msg, ...);
virtual void ERROR_MSG(const std::string& appender, const char* msg, ...);
virtual void FATAL_MSG(const std::string& appender, const char* msg, ...);
virtual ~ILogger(){}
};
对于文件记录器
class FileLogger : public ILogger{
public:
void DEBUG_MSG(const std::string& appender,const char* msg, ...){....}
void INFO_MSG(const std::string& appender,const char* msg, ...){....}
void WARNING_MSG(const std::string& appender, const char* msg, ...){....}
void ERROR_MSG(const std::string& appender, const char* msg, ...){....}
void FATAL_MSG(const std::string& appender, const char* msg, ...){....}
virtual ~EmptyLogger(){}
};
and the empty logger like:
表示空记录器
class EmptyLogger : public ILogger{
public:
void DEBUG_MSG(const std::string& appender,const char* msg, ...){do nothing here}
void INFO_MSG(const std::string& appender,const char* msg, ...){do nothing here}
void WARNING_MSG(const std::string& appender, const char* msg, ...){do nothing here}
void ERROR_MSG(const std::string& appender, const char* msg, ...){do nothing here}
void FATAL_MSG(const std::string& appender, const char* msg, ...){do nothing here}
virtual ~FileLogger(){}
};
之后,在您创建记录器的地方可以是工厂制作宏以生成不同类型的记录器。
class LoggerFactory{
public:
static ILogger* getLogger(/*loggertype as argument*/){
#ifdef GLOG_SILENCE
/* create a normal logger*/
#else
return new EmptyLogger();
#endif
}
};