使用预处理器宏来定义未定义的函数

时间:2012-04-19 10:26:33

标签: c++ c-preprocessor

我有一个用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是一个类有关,但我不知道该怎么做。 一些帮助?

3 个答案:

答案 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
 }
};