[英]Using the only the preprocessor for string concatenation?
Is it possible to concatenate quoted string literals outside of the language (C++, in this case)?是否可以连接语言之外的带引号的字符串文字(在本例中为 C++)?
That is, can I define MY_MACRO(a,b,c)
and use it thus:也就是说,我可以定义
MY_MACRO(a,b,c)
并使用它:
MY_MACRO("one", "two", "three")
and have it expand to: "onetwothree"
?并将其扩展为:
"onetwothree"
?
The use case is to apply an attribute and its message to, say, a function signature, like so:用例是将属性及其消息应用于函数签名,如下所示:
MY_ATTRIBUTE_MACRO("this", "is", "the reason") int foo() { return 99; }
and it would result in:这将导致:
[[nodiscard("thisisthe reason")]] int foo() { return 99; }
The language already does string concatenation!该语言已经进行了字符串连接!
This:这个:
"hi" "James"
becomes just one string literal.变成只是一个字符串文字。
That means you do not need any preprocessor tricks for this at all.这意味着您根本不需要任何预处理器技巧。
You need only employ this in the output of your macro:您只需要在宏的输出中使用它:
#define MY_ATTRIBUTE_MACRO(x,y,z) [[nodiscard(x y z)]]
Now this:现在这个:
MY_ATTRIBUTE_MACRO("this", "is", "the reason") int foo() { return 99; }
is this:这是:
[[nodiscard("this" "is" "the reason")]] int foo() { return 99; }
which is actually already what you wanted, because of the implicit string concatenation (which happens after macro expansion):这实际上已经是您想要的,因为隐式字符串连接(发生在宏扩展之后):
[[nodiscard("thisisthe reason")]] int foo() { return 99; }
[lex.phases]/4:
Preprocessing directives are executed, macro invocations are expanded , and _Pragma unary operator expressions are executed.[lex.phases]/4:
执行预处理指令,扩展宏调用,并执行_Pragma 一元运算符表达式。 If a character sequence that matches the syntax of a universal-character-name is produced by token concatenation, the behavior is undefined.如果与通用字符名称的语法匹配的字符序列是通过标记串联生成的,则行为未定义。 A
#include
preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively.#include
预处理指令使指定的头文件或源文件从阶段 1 到阶段 4 以递归方式进行处理。 All preprocessing directives are then deleted.然后删除所有预处理指令。
[lex.phases]/6:
Adjacent string literal tokens are concatenated.[lex.phases]/6:
相邻的字符串文字标记。
I'm not sure what you mean by "outside the language" but, in C++, any string literals separated just by whitespace are implicitly concatenated into one.我不确定您所说的“语言之外”是什么意思,但是在 C++ 中,任何仅由空格分隔的字符串文字都会隐式连接为一个。 Thus, your
MY_MACRO
definition is actually very simple:因此,您的
MY_MACRO
定义实际上非常简单:
#include <iostream>
#define MY_MACRO(a, b, c) a b c
int main()
{
std::cout << MY_MACRO("one", "two", "three") << std::endl;
return 0;
}
The output from this short program is what you asked for: onetwothree
.这个简短程序的输出是您所要求的:
onetwothree
。
Note: As a matter of curiosity/interest, it is normally recommended to enclose macro arguments in parentheses, in the definition part, so as to avoid unwanted side effects of the evaluation.注意:出于好奇/兴趣,通常建议将宏参数括在括号中,在定义部分,以避免评估的不必要的副作用。 However, in this case, using such parentheses won't work, and breaks the implicit concatenation:
但是,在这种情况下,使用这样的括号将不起作用,并且会破坏隐式连接:
#define MY_MACRO(a, b, c) (a) (b) (c) // Broken!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.