在下面的代码中,
##
是用来做什么的? #define MAKE_TYPE(myname) \
typedef int myname ## Id; \
##
表示连接。在这里,MAKE_TYPE(test)
将展开为:typedef int testId
。
根据16.3.3(##运算符)的规定:
对于对象式和函数式的宏调用,在重新检查替换列表以查找更多要替换的宏名称之前,将删除替换列表中每个非参数中的##预处理标记,并将前面的预处理标记与后面的预处理标记连接起来。MAKE_TYPE(OBJECT(Foo))
,那么您将拥有typedef int OBJECT(Foo)Id;
...这显然是无效的。处理宏是很麻烦的,最好避免使用,特别是在这种仅混淆事情的琐碎情况下。 - Matthieu M.icecrime是正确的,但在定义中需要指出的重要一点是,标记必须是有效的预处理标记。例如:
#define CONCAT(a,b) a ## b
CONCAT(ClassyClass, <int>); // bad, <int> is not a valid preprocessing token
CONCAT(Symbol, __LINE__); // valid as both are valid tokens