要在我的程序中打印调试消息,我可以这样使用:
DBG(5) << "Foobar" << std::endl;
5表示消息的级别,如果调试级别小于5,则不会打印消息。目前它的实现方式如下:
#define DBG(level) !::Logger::IsToDebug((level)) ? : ::Logger::Debug
基本上IsToDebug
检查是否应该打印消息,并在应该打印时返回true。 Logger::Debug
是一个std :: ostream。这也适用于gcc和clang,但是clang生成表达式结果未使用的警告。根据{{3}},这也不想改变。
使用(void)
作为前缀不起作用,它只会在?
之前强制转换,导致编译错误(无法将void转换为bool)。此语法的另一个问题是它使用this email。
像#define DBG(x) if (::Logger::IsToDebug((x))) ::Logger::Debug
这样的事情解决了这个问题,但这肯定会打破你的程序(if (foo) DBG(1) << "foo"; else ...
)(我不能把整个事情都归入do { ... } while(0)
宏被称为。)
我想出的唯一或多或少可行的解决方案就是这样(假设IsToDebug
返回0或1):
#define DBG(level) for(int dbgtmpvar = ::Logger::IsToDebug((level)); \
dbgtmpvar > 0; --dbgtmpvar) ::Logger::Debug
这似乎是一种过度杀伤(不计算它的运行时开销)
答案 0 :(得分:4)
我认为你应该使用三元运算符,因为它是在标准中定义的,而不是编译器扩展。要使用标准三元运算符,您还需要提供第二个表达式。为此,您可以定义一个流类,派生自std::ostream
,它不会向任何地方打印任何内容。这样一个类的对象可以用作第二个表达式。
class oemptystream : std::ostream
{
//..
};
extern oemptystream nout; //declaration here, as definition should go to .cpp
然后
#define DBG(level) ::Logger::IsToDebug((level))? nout : ::Logger::Debug
现在,如果您使用此宏,那么在运行时,表达式将减少为:
nout << "message";
或者这个,
::Logger::Debug << "message";
无论哪种方式,它都是这样的:
std::cout << "message";
所以我希望它不应该给编译器警告。