2011-12-08 48 views
7

我正在写一个记录器。如果禁用,这是定义LOG宏的代码:空流,我必须包括ostream吗?

#ifdef NO_LOG 

#include <ostream> 

struct nullstream : std::ostream { 
    nullstream() : std::ios(0), std::ostream(0) {} 
}; 

static nullstream logstream; 

#define LOG if(0) logstream 

#endif 

LOG << "Log message " << 123 << std::endl; 

它工作正常。编译器应该完全删除与LOG宏有关的代码。

但是我想避免包含ostream并将logstream对象定义为真的“轻”,可能为null。

谢谢!

回答

12
// We still need a forward declaration of 'ostream' in order to 
// swallow templated manipulators such as 'endl'. 
#include <iosfwd> 

struct nullstream {}; 

// Swallow all types 
template <typename T> 
nullstream & operator<<(nullstream & s, T const &) {return s;} 

// Swallow manipulator templates 
nullstream & operator<<(nullstream & s, std::ostream &(std::ostream&)) {return s;} 

static nullstream logstream; 

#define LOG if(0) logstream 

// Example (including "iostream" so we can test the behaviour with "endl"). 
#include <iostream> 

int main() 
{ 
    LOG << "Log message " << 123 << std::endl; 
} 
+0

它的工作,但是有可能避免包含iostream?例如,是否可以使用别的东西而不是std :: endl? –

+0

@Pietro:对于'std :: endl'来说,只需要这个例子。 'nullstream'本身并不需要,只是''(类型的前向声明)。 –

+0

@Pietro通常可以使用'\ n'而不是std :: endl。 – UncleBens

5

为什么不从头实现整个事情:

struct nullstream { }; 

template <typename T> 
nullstream & operator<<(nullstream & o, T const & x) { return o; } 

static nullstream logstream; 
+2

这应该是'nullstream',而不是'的std :: ostream'? – sth

+2

你的意思是'nullstream&operator <<(nullstream&o,T const&x)'?它不会与'endl'一起使用。 – fefe

+0

@fefe:你说得对;目前,endl似乎是唯一的问题。是否有可能以另一种方式终止一个流。如果我不需要日志记录,我真的想避免包含ostream ... –