我试图使用宏来根据类型调用适当的对象。
#define DELEGATE_FUNC(FuncName, kind, paramPtr) \
if (kind == 1) { \
return PolicyObject1.##FuncName(paramPtr); \
} \
else { \
return PolicyObject2.##FuncName(paramPtr); \
} \
return 0; \
(PolicyObject1和PolicyObject2是两个静态对象。)现在使用宏时,例如
DELEGATE_FUNC(ProcessPreCreate,1,null_ptr);
它在VS 2015中编译得很好,但在LLVM中出错“粘贴形成了一个无效的处理令牌'.ProcessPreCreate'”
我寻找,并找到了一些帖子,并将其理解到某种程度 - 需要双重间接,例如, Why do I need double layer of indirection for macros?
但是我无法定义那两层宏,有人可以帮忙吗?
(请不要讨论设计方面的问题)
谢谢
当编译器读取您的C ++文件时,其中一个步骤是将其分为标识符,字符串文字,数字,标点符号等标记.C预处理程序可以处理这些标记,而不是文本。 ##
操作员将令牌粘在一起。所以,例如,如果你有
#define triple(foo) foo##3
然后triple(x)
将获得标识符x3
,triple(12)
将获得整数123
,triple(.)
将获得浮动.3
。
然而,你所拥有的是.##FuncName
,其中FuncName
是ProcessPreCreate
。这将创建单个标记.ProcessPreCreate
,它不是有效的C ++标记。如果您直接键入PolicyObject1.ProcessPreCreate
而不是通过宏,它将被标记为三个标记:PolicyObject1
,.
和ProcessPreCreate
。这是您的宏需要生成以提供有效的C ++输出。
要做到这一点,只需摆脱##
。没有必要将.
粘贴到FuncName
上,因为它们是单独的令牌。要检查这一点,你可以在.
和成员名称之间加一个空格;它仍然可以正常编译。由于它们是独立的令牌,因此它们不应该也不能粘在一起。
删除“##”。
#define DELEGATE_FUNC(FuncName, kind, paramPtr) \
if (kind == 1) { \
return PolicyObject1.FuncName(paramPtr); \
} \
else { \
return PolicyObject2.FuncName(paramPtr); \
} \
return 0; \