Jam*_*mes 0 c++ preprocessor c-preprocessor
是否可以连接语言之外的带引号的字符串文字(在本例中为 C++)?
也就是说,我可以这样定义MY_MACRO(a,b,c)和使用它:
MY_MACRO("one", "two", "three")
Run Code Online (Sandbox Code Playgroud)
并将其扩展为:"onetwothree"?
用例是将属性及其消息应用于函数签名,如下所示:
MY_ATTRIBUTE_MACRO("this", "is", "the reason") int foo() { return 99; }
Run Code Online (Sandbox Code Playgroud)
这将导致:
[[nodiscard("thisisthe reason")]] int foo() { return 99; }
Run Code Online (Sandbox Code Playgroud)
该语言已经进行了字符串连接!
这个:
"hi" "James"
Run Code Online (Sandbox Code Playgroud)
变成只是一个字符串文字。
这意味着您根本不需要任何预处理器技巧。
您只需要在宏的输出中使用它:
#define MY_ATTRIBUTE_MACRO(x,y,z) [[nodiscard(x y z)]]
Run Code Online (Sandbox Code Playgroud)
现在这个:
MY_ATTRIBUTE_MACRO("this", "is", "the reason") int foo() { return 99; }
Run Code Online (Sandbox Code Playgroud)
这是:
[[nodiscard("this" "is" "the reason")]] int foo() { return 99; }
Run Code Online (Sandbox Code Playgroud)
这实际上已经是您想要的,因为隐式字符串连接(发生在宏扩展之后):
[[nodiscard("thisisthe reason")]] int foo() { return 99; }
Run Code Online (Sandbox Code Playgroud)
[lex.phases]/4:执行预处理指令,扩展宏调用,并执行 _Pragma 一元运算符表达式。如果与通用字符名称的语法匹配的字符序列是通过标记串联产生的,则行为是未定义的。甲#include预处理指令导致从第1阶段至第4阶段处理指定的头或源文件,递归。然后删除所有预处理指令。
[lex.phases]/6:连接相邻的字符串文字标记。