C++ 如何在发布模式下自动注释行?

C++ 如何在发布模式下自动注释行?,c++,debugging,c-preprocessor,release,release-mode,C++,Debugging,C Preprocessor,Release,Release Mode,我只需要在调试模式下激活一些代码行,在发布模式下忽略这些代码行。 有没有办法做到这一点: #include <iostream> using namespace std; #ifdef _TEST_ #define _cerr cerr #else #define _cerr // cerr #endif int main() { _cerr << "TEST message" << endl; } if (something) _cerr &

我只需要在调试模式下激活一些代码行,在发布模式下忽略这些代码行。 有没有办法做到这一点:

#include <iostream>
using namespace std;

#ifdef _TEST_
#define _cerr cerr
#else
#define _cerr // cerr
#endif

int main() {
   _cerr << "TEST message" << endl;
}
if (something)
  _cerr << "Why?" << std::endl;
#包括
使用名称空间std;
#ifdef_试验_
#定义
#否则
#定义_cerr//cerr
#恩迪夫
int main(){

_cerrIFDEF是一种方法。否则,您如何知道编译器是否处于“发布”与“调试”模式?除了在预处理阶段,什么时候会进行通信?除了在模板生成期间,您还可以在什么其他阶段决定删除/添加代码.嘿,也许我们可以使用模板生成…但您仍然必须以某种方式关闭ifdef以控制您的模板

也许有一种我没有想到的非常巧妙的方法可以做到这一点,但是每个人都知道/使用ifdef来实现这一目的。如果你扔给他们一个曲线球,那只会大大增加维护代码的人力成本


请坚持使用ifdef。

您可以使用宏执行以下操作:

#ifdef _TEST_
#define DEBUG_ONLY(x) x;
#else
#define DEBUG_ONLY(x)
#endif

int main() {
    DEBUG_ONLY(cerr << "TEST message" << endl)
}
\ifdef\u测试_
#仅定义调试_(x)x;
#否则
#仅定义调试单元(x)
#恩迪夫
int main(){
仅调试(cerr
int main(){
#ifdef_试验_
_cerr使用以下方法:

#ifdef _TEST_
#define DEBUG_TEST(x) x
#else
#define DEBUG_TEST(x)
#endif

int main() {
    DEBUG_TEST(_cerr << "TEST message" << endl);
}
\ifdef\u测试_
#定义调试测试(x)x
#否则
#定义调试测试(x)
#恩迪夫
int main(){
调试测试(\u cerrNo

请尝试此选项的变体:

#ifdef _TEST_
    ostream& _cerr = cerr;
#else
    ostringstream _cerr;
#endif

(基本上,您需要一个只丢弃其输入的流。)

这里基本上满足了您的要求:

#ifdef _TEST_
#define _cerr  cerr
#else
#define _cerr  if (1) {} else cerr
#endif
但是,如果您在编写类似以下内容时收到编译器关于不明确
else
的警告,请不要感到惊讶:

#include <iostream>
using namespace std;

#ifdef _TEST_
#define _cerr cerr
#else
#define _cerr // cerr
#endif

int main() {
   _cerr << "TEST message" << endl;
}
if (something)
  _cerr << "Why?" << std::endl;
if(某物)

_cerr将_cerr定义为nothing将导致编译失败。您可以改为定义在发布模式下排除的宏

例如:

#ifdef _TEST_
#define LOG_ERROR(log) cerr << log << endl;
#else
#define LOG_ERROR(log) 
#endif

如果您所追求的是在发布版本中删除的调试日志记录,则可以执行以下操作:

#ifdef _TEST_
#define LOG(x) (cerr << x << endl)
#else
#define LOG(x)
#endif

...

int main() {
    LOG("TEST message");
}
\ifdef\u测试_
#定义LOG(x)(cerr对于“无登录版本”来说,更好的解决方案是以下类:

class NullStream {
   template<typename T> NullStream& operator<< const(T&) { }
};

创建自己的空流

#include <iostream>

class NullStream    {};
template<typename T>
NullStream& operator <<(NullStream& n,T const& data)                        {return n;}
NullStream& operator <<(NullStream& n,std::ostream& (*)(std::ostream&))     {return n;}

#ifdef  _TEST_
#define myerr       std::cerr
#else
NullStream  myerrstream;
#define myerr       myerrstream
#endif

int main()
{
    myerr << "Hi" << std::endl;;
    myerr << std::endl;;
}
#包括
类NullStream{};
模板

NullStream&运算符首先,我认为使用带有下划线前缀的全局名称是为实现保留的。其次,丢弃输入的流不会阻止参数的计算,这使得这种方法在任何性能敏感的上下文中都是无用的。不在宏中添加分号会使UR代码更像C++(强制用户添加<代码>;<代码> >代码> Debug只/ <代码>子句)。我看到的这个宏的惟一问题是,你只限于一个语句。我个人更喜欢<代码> do{x;}而(0)子句允许宏中的多个语句(即使一些编译器抱怨<代码>),而(0)
部分…:/)他并没有试图将其定义为空。他希望注释斜杠将包含在宏扩展中,这样结果将是一个注释掉的日志行。不太好:参数将被计算…即使这是无用的!没错,但是当您写入例如stringstream时,您也会遇到这个问题。这节省了开销
运算符的定义
#include <iostream>

class NullStream    {};
template<typename T>
NullStream& operator <<(NullStream& n,T const& data)                        {return n;}
NullStream& operator <<(NullStream& n,std::ostream& (*)(std::ostream&))     {return n;}

#ifdef  _TEST_
#define myerr       std::cerr
#else
NullStream  myerrstream;
#define myerr       myerrstream
#endif

int main()
{
    myerr << "Hi" << std::endl;;
    myerr << std::endl;;
}