使用唯一的预处理器进行字符串连接?

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)

Ast*_*ngs 5

该语言已经进行了字符串连接!

这个:

"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)

翻译阶段4

[lex.phases]/4: 执行预处理指令,扩展宏调用,并执行 _Pragma 一元运算符表达式。如果与通用字符名称的语法匹配的字符序列是通过标记串联产生的,则行为是未定义的。甲#include预处理指令导致从第1阶段至第4阶段处理指定的头或源文件,递归。然后删除所有预处理指令。

翻译阶段6

[lex.phases]/6: 连接相邻的字符串文字标记。