调试日志语句的预处理器宏在C++;? 最近我一直在阅读Scott Meyers的C++第二版,以改进C++最佳实践。他列出的一个项目鼓励C++程序员避免预处理器宏和“编译器”。他说,除了C++包含和αIFIFF/αIFNDEF之外,C++中的宏几乎没有理由。

调试日志语句的预处理器宏在C++;? 最近我一直在阅读Scott Meyers的C++第二版,以改进C++最佳实践。他列出的一个项目鼓励C++程序员避免预处理器宏和“编译器”。他说,除了C++包含和αIFIFF/αIFNDEF之外,C++中的宏几乎没有理由。,c++,debugging,logging,macros,c-preprocessor,C++,Debugging,Logging,Macros,C Preprocessor,我同意他的推理,因为你可以完成以下宏 #define min(a,b) ((a) < (b) ? (a) : (b)) 这个宏提供了难以置信的实用程序,我想把它应用到我的C++程序中。编写有用的日志语句非常简单 CCLOG(@"Error in x due to y"); 更好的是,如果COCOS2D_调试设置为0,那么这些语句就永远看不到曙光。检查条件语句以查看是否应该使用日志语句没有开销。这在从开发过渡到生产时非常方便。如何在C++中重新产生同样的效果? 这类宏属于C++程序吗?是

我同意他的推理,因为你可以完成以下宏

#define min(a,b) ((a) < (b) ? (a) : (b))

这个宏提供了难以置信的实用程序,我想把它应用到我的C++程序中。编写有用的日志语句非常简单

CCLOG(@"Error in x due to y");
更好的是,如果COCOS2D_调试设置为0,那么这些语句就永远看不到曙光。检查条件语句以查看是否应该使用日志语句没有开销。这在从开发过渡到生产时非常方便。如何在C++中重新产生同样的效果?


这类宏属于C++程序吗?是否有更好的,更C++的方式来做这个?

< P>,史葛的陈述是在宏是 由于历史原因,使用过度。尽管如此 通常情况下,在一些情况下宏是有意义的。 其中之一是日志记录,因为只有宏才能自动 插入
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
\uuuuuuuuuuuuuuuuuuuuuuuuuu行
。此外,只有宏可以 决心什么都不做(尽管根据我的经验, 这没什么大不了的)

宏如你所显示的在C++中不是很频繁。有 日志记录的两种常见变体:

#define LOG( message ) ... << message ...
其中,
logFile
返回
std::ostream
的包装,其中 定义
operator宏有“正确”的用途,也有不好的用途。在函数工作的地方使用宏是个坏主意。在我的书中,在函数不执行相同操作的情况下使用宏是非常好的

我经常使用这样的结构:

#defien my_assert(x) do { if (!x) assert_failed(x, #x, __FILE__, __LINE__); } while(0)

template<typename T> 
void assert_failed(T x, const char *x_str, const char *file, int line)
{
   std::cerr << "Assertion failed: " << x_str << "(" << x << ") at " << file << ":" << line << std::endl;
   std::terminate();
}
enum E
{
   a, 
   b, 
   c,
   d
 };

 struct enum_string
 {
    E v;
    const char *str;
 };

 #define TO_STR(x) { x, #x }

 enum_string enum_to_str[] = 
 {
    TO_STR(a),
    TO_STR(b),
    TO_STR(c),
    TO_STR(d),
  };
节省了很多重复的东西


所以,是的,它在某些情况下是有用的

我相信你的“CCLOG()”是一个很好的例子,说明了宏在哪里是有用的和合适的。嗯……嗯,
min
template函数与宏的作用不同。尝试一下
min(1,2L)
@PeteBecker我不是模板大师,但会不会是因为1是int,2L是long?我提供的模板声明将只为同一类型的两个对象生成函数。@PaulRenton-是的,的确如此。这并不会使模板变差;这是标准库中定义
min
的方式。@PeteBecker很好。我要指出,它们并不完全相似。
#define LOG() logFile( __FILE__, __LINE__ )
LOG() << "x = " << x;
#defien my_assert(x) do { if (!x) assert_failed(x, #x, __FILE__, __LINE__); } while(0)

template<typename T> 
void assert_failed(T x, const char *x_str, const char *file, int line)
{
   std::cerr << "Assertion failed: " << x_str << "(" << x << ") at " << file << ":" << line << std::endl;
   std::terminate();
}
enum E
{
   a, 
   b, 
   c,
   d
 };

 struct enum_string
 {
    E v;
    const char *str;
 };

 #define TO_STR(x) { x, #x }

 enum_string enum_to_str[] = 
 {
    TO_STR(a),
    TO_STR(b),
    TO_STR(c),
    TO_STR(d),
  };