预处理器对我来说一直是黑魔法,但我想我最终需要使用它。
我已经实现了一个记录器类,如果没有设置标志,我想有条件地(编译标志)扩展为空,这样我就不能在生产中获得所有的打印。
这将有一个像这样的用例
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();\
^~~~~~~~~~~~~~~~~~~~~
现在错误很明显,但我不知道如何在预处理器语法中表达我的意图...
答案 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对象。您可以在程序中创建一次,然后向前声明它以避免这种情况。但它并不那么优雅。