如何理解这个关于C ++中的define的代码示例?

时间:2013-03-26 03:06:43

标签: c++ c-preprocessor

#define EVENT_TYPE(DO) DO(EVENT_UNKNOWN), DO(EVENT_SIP), DO(EVENT_MEDIA), \
                     DO(EVENT_APP), DO(EVENT_TIMER), DO(EVENT_BREAK),  \
                     DO(EVENT_STOP), DO(EVENT_MAX)

如何理解这个关于C ++中的define的代码示例?

2 个答案:

答案 0 :(得分:2)

宏是简单的替换。所以无论你把它放在EVENT_TYPE的arg中取代,你在右边的事件列表中看到“DO”。例如,EVENT_TYPE( GUI )将替换为:

GUI(EVENT_UNKNOWN), GUI(EVENT_SIP), GUI(EVENT_MEDIA), \
GUI(EVENT_APP), GUI(EVENT_TIMER), GUI(EVENT_BREAK),   \
GUI(EVENT_STOP), GUI(EVENT_MAX)

这可能是为了与其他宏一起使用,以便GUI(或其中的任何内容)本身就是一个宏,可以做一些事情,例如,在命名空间之前(所以第一个元素)变为MyNamespace :: MyUI :: EVENT_UNKNOWN)或连接标识符字符串(因此第一个元素变为GUI_EVENT_UNKNOWN)。

<强>更新: 来自您的评论:

#define STRINGIFY(VAR) #VAR

使用var中的任何内容创建一个字符串。通常,这将是一个变量名称,但它可以是一个表达式。因此预处理器将转换:

int i = 42;
std::cout << STRINGIFY(i)   << " = " << i << '\n' 
          << STRINGIFY(i+1) << " = " << i+1 << '\n';

int i = 42;
std::cout << "i"   << " = " << i << '\n' 
          << "i+1" << " = " << i+1 << '\n';

将打印:

i = 42
i+1 = 43

您也可以进行符号连接:

#define CONCAT(X) prefix_##X##_suffix

int CONCAT(myVar) = 42;

将成为:

int prefix_myVar_suffix = 42;

您也可以进行字符串连接,但我会将其作为读者的练习。

答案 1 :(得分:1)

它执行文本替换以将DO替换为您提供的任何内容,例如函数或函子。生成的代码会为DO,...中的每一个调用您传递的仿函数函数代替EVENT_UNKNOWN,并返回它们,就好像您将它们放置为a,b,c一样。

您可以使用它来创建一组事件的枚举。例如:

// create array of all of EVENT_UKNOWN... as integers
int array[] = { EVENT_TYPE((int)) };

// Create array of strings
class Foo {
public:
   std::string operator()(int val) { ... }
};

Foo f;
std::string strings[] = { EVENT_TYPE(f); }