【问题标题】:How to understand this code sample about define in C++? [closed]如何理解这个关于在 C++ 中定义的代码示例? [关闭]
【发布时间】:2013-03-26 03:06:42
【问题描述】:
#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++ 中定义的代码示例?

【问题讨论】:

  • 通过查找传递给它的内容 (DO) 和相关参数。如果没有它,我们怎么可能告诉你它做了什么?

标签: c++ c-preprocessor


【解决方案1】:

宏是简单的替换。因此,无论您在 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;

您也可以进行字符串连接,但我将把它作为练习留给读者。

【讨论】:

  • #define MAKE_STRINGS(VAR) #VAR 怎么样?
【解决方案2】:

它会进行文本替换以将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); }

【讨论】:

  • 谢谢,#define MAKE_STRINGS(VAR) #VAR
  • 宏扩展中的 # 被称为字符串化,或者用确切的字符串文字替换。因此,EVENT_TYPE(MAKE_STRINGS) 将返回每个“EVENT_UNKNOWN”的逗号分隔的字符串列表,...
猜你喜欢
  • 2017-03-23
  • 1970-01-01
  • 2019-12-07
  • 2016-02-22
  • 1970-01-01
  • 2015-12-09
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多