【发布时间】:2013-10-30 02:16:41
【问题描述】:
阅读一些 C++ 代码时,我遇到了我称之为函数宏的“函数式”使用,大致如下(这是一个完全程式化的例子来说明这一点):
#define TOP_LEVEL(ARG1) \
ARG1("foo1","bar1") \
ARG1("foo2","bar2")
#define NEXT_LEVEL(ARG2A, ARG2B) \
cout << ARG2A << " and " << ARG2B;
TOP_LEVEL(NEXT_LEVEL)
我对这门语言比较陌生,起初我无法弄清楚,但后来我只通过预处理器 (g++ -E) 运行它,结果发现它解析为:
cout << "foo1" << " and " << "bar1"; cout << "foo2" << " and " << "bar2";
你看到它在那里做了什么吗?它将宏 NEXT_LEVEL 像函数指针传递给宏 TOP_LEVEL。看到这可能有多么有用,我想了解更多信息:将函数传递给其他函数是pretty sophisticated stuff,并且必须至少有更多关于该技术的内容要说。
尽管在谷歌上搜索了很多,但我找不到任何证据表明预处理器的这个功能甚至存在,更不用说任何接近文档的东西了:here、here、here 和 here 只是四个例子跳过此内容的宏教程;最后一个甚至有一个名为“高级宏技巧”的部分 - 这肯定符合条件!?
(请注意,这与简单地以另一个 求值 函数宏作为参数调用函数宏完全不同 - FOO(BAR(2)) 更直接。)
我的问题是:
- 此行为是否有实际名称?
- 它是否记录在任何地方?
- 是常用的,还是有众所周知的陷阱等?
【问题讨论】:
-
该术语是一个 X 宏。一般用多一点,比如说,gusto;一个宏是在包含一个头文件之前定义的,该头文件期望该宏可以按照自己的意愿处理数据。
-
哇 - 感谢您的快速回答。我很高兴在 X-Macros 的 Wikipedia 页面上读到,尽管它们自 1960 年代就已经存在,但它们是“relatively unkown”——所以至少不仅仅是我 ;-)
-
是的。 :) 我会让别人写一个关于它的好答案,但如果没有人解决它,我会的。
-
关于宏语言的这一特性的文献并不多,我并不感到惊讶,一般来说,宏被认为是利大于弊。我已经使用该技巧进行了几次自动代码生成(定义一个
FOR_EACH_ENUMERATOR,它接受一个宏,然后使用两个参数(enumerator,value)应用它。然后使用该宏在枚举和转换函数中创建值从/到用于日志记录/io 的字符串...我曾尝试使用该宏在某一时刻提供反射,但除了那个程序之外,我以后没有使用它... -
是的,Boost.PP 有一些很好的例子。
标签: c++ c-preprocessor x-macros