预处理器,未定义时将宏展开为空

Preprocessor, expand macro to nothing when undefined

预处理器对我来说一直是黑魔法,但我想我终于需要使用它了。

我已经实现了一个记录器 class 如果未设置标志,我想有条件地(编译标志)扩展为空,这样我就不会在生产中获得所有打印件。

这会有一个像这样的用例

FO_LOG << name() << "Hello World"  << std::endl;

我以为我可以这样定义它

#ifdef TRACE
#define FO_LOG {return Faceoff::trace::log();}
#else
#define FO_LOG \
    if(false){\
        return Faceoff::trace::log();\
    }
#endif

但这不会编译并出现以下错误

no viable conversion from returned value of type 'Faceoff::trace' to function return type 'int'
                FO_LOG << name() << "omitted"  << std::endl;
                ^~~~~~
    /omitted/include/globals.h:69:16: note: expanded from macro 'FO_LOG'
            return Faceoff::trace::log();\
                   ^~~~~~~~~~~~~~~~~~~~~

现在错误清楚了,但我不知道如何用预处理器语法表达我的意图...

给你:

class devnull : public std::ostream {
    class devnullbuff : public std::streambuf {
    public:
        int overflow( int c ) { return c; }
    } m_nb;
public:
    devnull() : std::ostream( &m_nb ) {}
};
#ifdef TRACE
#define FO_LOG Faceoff::trace::log()
#else
#define FO_LOG devnull()
#endif

假设 Faceoff::trace::log() returns 某种 ostream,那么你可以做你想做的事:

FO_LOG << name() << "Hello World"  << std::endl;

这不是很有效,因为它每次都会创建一个新的 devnull 对象。您可以在您的程序中只创建一次并转发声明以避免这种情况。虽然没有那么优雅。