C++ 使用预处理器取消std::cout代码行

C++ 使用预处理器取消std::cout代码行,c++,c-preprocessor,cout,C++,C Preprocessor,Cout,可以使用#define printf删除对printf()的所有调用。如果我有很多调试输出,比如std::cout用如下内容替换调试输出语句,该怎么办 IFDBG(cout << result << endl); 您可能可以使用名为cerr的实例来执行预处理器hack,它定义了一个新的类似流的类,但什么都不做。如果您真的很幸运,编译器将看到函数什么也不做,并优化对操作符的调用,因为一般原则上应该避免记录到stdout,最好是记录到日志文件,然后您可以使用标准配置工具更改

可以使用
#define printf
删除对
printf()的所有调用。如果我有很多调试输出,比如
std::cout用如下内容替换调试输出语句,该怎么办

IFDBG(cout << result << endl);

您可能可以使用名为
cerr
的实例来执行预处理器hack,它定义了一个新的类似流的类,但什么都不做。如果您真的很幸运,编译器将看到函数什么也不做,并优化对
操作符的调用,因为一般原则上应该避免记录到stdout,最好是记录到日志文件,然后您可以使用标准配置工具更改日志级别,或者完全关闭它

就我的$0.02….

正如“放松”所说,快速解决方案是不做任何事情。不过,还有更好的实现:

class NullStream {
    public:
    NullStream() { }
    template<typename T> NullStream& operator<<(T const&) { return *this; }
};

如果您正在寻找快速删除调试语句的方法,那么NullStream可能是一个很好的解决方案。但是,我建议您创建自己的调试类,当需要更多调试功能时,可以根据需要扩展该类:

class MyDebug
{
    std::ostream & stream;
  public:
    MyDebug(std::ostream & s) : stream(s) {}
#ifdef NDEBUG
    template<typename T>
    MyDebug & operator<<(T& item)
    {
      stream << item;
      return *this;
    }
#else
    template<typename T>
    MyDebug & operator<<(T&)
    {
      return *this;
    }
#endif
};
类MyDebug
{
标准::ostream&stream;
公众:
MyDebug(std::ostream&s):流{}
#ifdef-NDEBUG
模板

MyDebug&operator定义一个宏来替换
cout
不是你应该上传到你的VCS的东西,但是如果你只是在调试过程中临时执行,我认为它是合适的。所以你可以用
ostream(0)
来替换
cout

#ifdef NDEBUG
#define cout ostream(0).flush()
#endif
通过这种方式,它可以与
std::cout
和普通
cout
一起工作,并且
ostream
在包含
时可用。写入
ostream(0)
是不可操作的。执行
flush
函数调用是为了获得对它的非常量引用(因此它还绑定到非成员
运算符定义此宏:

#ifdef DEBUG
    #define MY_LOG std::cout
#else
    #define MY_LOG if(false) std::cout
#endif
宏的优势在于编译器优化

如果这些IFs中的表达式在编译时是常量和可确定的,那么您几乎可以确定编译器已经为您从代码中删除了它们。。。


这看起来不适用于
IFDBG(不,这不会破坏宏,因为宏可以用括号转义作用域。但是这个调用会破坏它:IFDBG(如果我将endl传递给这个流,它会给出错误。。看起来T&item不接受endl。。有没有关于如何重载它的线索?非常感谢,我很感激。)
class MyDebug
{
    std::ostream & stream;
  public:
    MyDebug(std::ostream & s) : stream(s) {}
#ifdef NDEBUG
    template<typename T>
    MyDebug & operator<<(T& item)
    {
      stream << item;
      return *this;
    }
#else
    template<typename T>
    MyDebug & operator<<(T&)
    {
      return *this;
    }
#endif
};
MyDebug & operator<<(std::ostream & (*pf)(std::ostream&))
{
  stream << pf;
  return *this;
}
template<typename R, typename P>
MyDebug & operator<<(R & (*pf)(P &))
{
  stream << pf;
  return *this;
}
#ifdef NDEBUG
#define cout ostream(0).flush()
#endif
#ifdef DEBUG
    #define MY_LOG std::cout
#else
    #define MY_LOG if(false) std::cout
#endif