是否可以在多行字符串文本中使用 C/C++ 预处理器令牌

Can you use C/C++ preprocessor tokens in multiline string literals

本文关键字:C++ 预处理 令牌 处理器 文本 字符串 是否      更新时间:2023-10-16

扩展这个问题和这个问题,是否可以使用所示的预处理器方法或包含预处理器符号值的多行字符串文本C++多行字符串文本。 例如:

#define SOME_CONSTANT 64
#define QUOTE(...) #__VA_ARGS__
const char * aString = QUOTE(
{
"key":"fred",
"value":"SOME_CONSTANT"
}
);

理想情况下,我希望将"SOME_CONSTANT"替换为"64"。

我尝试使用我有限的技能中的所有技巧,包括串化,但没有运气。

有什么想法吗?

你有两个问题。首先是引号内的预处理器标记(即字符串文本(不会被替换。第二种情况是,您必须推迟实际的字符串化,直到替换所有预处理标记。字符串化必须是预处理器处理的最后一个宏。

令牌替换以迭代方式进行。预处理器处理替换,然后返回以查看在刚刚替换的序列中是否还有任何要替换的内容。我们需要利用它来发挥我们的优势。如果我们有一个假设的TO_STRING宏,我们需要下一次迭代来替换所有预处理令牌,并且只需要之后的迭代来生成对"真实"字符串化的调用。幸运的是,编写起来相当简单:

#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_指示的替换。