你能在多行字符串文字中使用 C/C++ 预处理器标记吗
Can you use C/C++ preprocessor tokens in multiline string literals
在 and this question 上扩展,是否可以使用所示的预处理器方法或包含预处理器符号值的 C++ 多行字符串文字来获得多行字符串文字。例如:
#define SOME_CONSTANT 64
#define QUOTE(...) #__VA_ARGS__
const char * aString = QUOTE(
{
"key":"fred",
"value":"SOME_CONSTANT"
}
);
理想情况下,我希望将 "SOME_CONSTANT" 替换为“64”。
我已经尝试使用我有限技能集中的所有技巧,包括 stringizing 但没有成功。
有什么想法吗?
你有两个问题。首先是引号内的预处理器标记(即字符串文字)不会被替换。第二个是您必须推迟实际的字符串化,直到所有预处理标记都被替换。字符串化必须是预处理器处理的最后一个宏。
令牌替换是迭代发生的。预处理器处理替换,然后返回查看它刚刚替换的序列中是否还有任何内容需要替换。我们需要利用它来发挥我们的优势。如果我们有一个假设的 TO_STRING
宏,我们需要下一次迭代来替换所有预处理标记,并且 仅 之后的迭代产生对 [=32= 的调用] 字符串化。幸运的是,写起来相当简单:
#define TO_STRING(...) DEFER(TO_STRING_)(__VA_ARGS__)
#define DEFER(x) x
#define TO_STRING_(...) #__VA_ARGS__
#define SOME_CONSTANT 64
#define QUOTE(...) TO_STRING(__VA_ARGS__)
const char * aString = QUOTE({
"key":"fred",
"value": TO_STRING(SOME_CONSTANT)
});
我们需要 DEFER
宏,因为预处理器不会在它识别为另一个宏的参数的内容中进行替换。这里的技巧是 DEFER(TO_STRING_)(x)
中的 x
不是宏的参数。所以它和 DEFER(TO_STRING_)
一样被替换了。我们得到的结果是 TO_STRING_(substituted_x)
。这将成为下一次迭代中的宏调用。因此预处理器将在先前替换的 x
.
上执行由 TO_STRING_
指示的替换
在
#define SOME_CONSTANT 64
#define QUOTE(...) #__VA_ARGS__
const char * aString = QUOTE(
{
"key":"fred",
"value":"SOME_CONSTANT"
}
);
理想情况下,我希望将 "SOME_CONSTANT" 替换为“64”。
我已经尝试使用我有限技能集中的所有技巧,包括 stringizing 但没有成功。
有什么想法吗?
你有两个问题。首先是引号内的预处理器标记(即字符串文字)不会被替换。第二个是您必须推迟实际的字符串化,直到所有预处理标记都被替换。字符串化必须是预处理器处理的最后一个宏。
令牌替换是迭代发生的。预处理器处理替换,然后返回查看它刚刚替换的序列中是否还有任何内容需要替换。我们需要利用它来发挥我们的优势。如果我们有一个假设的 TO_STRING
宏,我们需要下一次迭代来替换所有预处理标记,并且 仅 之后的迭代产生对 [=32= 的调用] 字符串化。幸运的是,写起来相当简单:
#define TO_STRING(...) DEFER(TO_STRING_)(__VA_ARGS__)
#define DEFER(x) x
#define TO_STRING_(...) #__VA_ARGS__
#define SOME_CONSTANT 64
#define QUOTE(...) TO_STRING(__VA_ARGS__)
const char * aString = QUOTE({
"key":"fred",
"value": TO_STRING(SOME_CONSTANT)
});
我们需要 DEFER
宏,因为预处理器不会在它识别为另一个宏的参数的内容中进行替换。这里的技巧是 DEFER(TO_STRING_)(x)
中的 x
不是宏的参数。所以它和 DEFER(TO_STRING_)
一样被替换了。我们得到的结果是 TO_STRING_(substituted_x)
。这将成为下一次迭代中的宏调用。因此预处理器将在先前替换的 x
.
TO_STRING_
指示的替换