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

时间:2018-04-14 21:02:02

标签: c++ preprocessor

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

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

这将有一个像这样的用例

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();\
                   ^~~~~~~~~~~~~~~~~~~~~

现在错误很明显,但我不知道如何在预处理器语法中表达我的意图...

1 个答案:

答案 0 :(得分:3)

你走了:

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()返回某种ostream,那么你可以做你想做的事:

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

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