C++ 字符串化 - 它是如何工作的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16989730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Stringification - how does it work?
提问by Marco A.
I know that:
我知道:
#define foo 4
#define str(s) #s
with str(foo)writes out: "foo", because stringify is executed first of text expansion, but this:
withstr(foo)写出: "foo",因为 stringify 首先执行文本扩展,但是:
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
with xstr(foo)writes out: "4".
与xstr(foo)写出:"4"。
Why? What are the steps involved in the process?
为什么?该过程涉及哪些步骤?
回答by Eric Postpischil
The relevant steps of macro expansion are (per C 2011 [n1570] 6.10.3.1 and C++ 1998 16.3.1):
宏扩展的相关步骤是(根据 C 2011 [n1570] 6.10.3.1 和 C++ 1998 16.3.1):
- Process tokens that are preceded by
#or##. - Apply macro replacement to each argument.
- Replace each parameter with the corresponding result of the above macro replacement.
- Rescan for more macros.
- 处理以
#或开头的标记##。 - 对每个参数应用宏替换。
- 用上述宏替换的相应结果替换每个参数。
- 重新扫描更多宏。
Thus, with xstr(foo), we have:
因此,对于xstr(foo),我们有:
- The replacement text,
str(s), contains no#or##, so nothing happens. - The argument
foois replaced with4, so it is as ifxstr(4)had been used. - In the replacement text
str(s), the parametersis replaced with4, producingstr(4). str(4)is rescanned. (The resulting steps produce”4”.)
- 替换文本
str(s)不包含#或##,因此什么也不会发生。 - 参数
foo被替换为4,因此就好像xstr(4)被使用过一样。 - 在替换文本中
str(s),参数s被替换为4,生产str(4)。 str(4)被重新扫描。(由此产生的步骤产生”4”.)
Note that the problem with str(foo)is that step 2, which would replace foowith 4, comes after step 1, which changes the argument to a string. In step 1, foois still foo; it has not been replaced with 4, so the result is ”foo”.
请注意,问题str(foo)在于第 2 步(将替换foo为4)在第 1 步之后,它将参数更改为字符串。在步骤 1 中,foo仍然是foo; 它没有被替换为4,所以结果是”foo”。
This is why a helper macro is used. It allows us to get a step 2 performed, then use another macro to perform step 1.
这就是使用辅助宏的原因。它允许我们执行第 2 步,然后使用另一个宏执行第 1 步。
回答by Lol4t0
First case
第一种情况
- Evaluate
str(foo): Substitutestr(foo)with#foo, ie"foo"
- 评估
str(foo):替换str(foo)为#foo,即"foo"
Second case
第二种情况
- Evaluate
xstr(foo): Substitutexstr(foo)withstr(<foo-value>), iestr(4) - Evaluate
str(4): Substitutestr(4)with#4, ie"4"
- 评估
xstr(foo):替换xstr(foo)为str(<foo-value>),即str(4) - 评估
str(4):替换str(4)为#4,即"4"
Generally,
一般来说,
preprocessor evaluates macro-functions expanding macro-variables, until it is nothing to evaluate:
预处理器评估宏函数扩展宏变量,直到它没有评估:
If you define
如果你定义
#define xstr(s) str(s) + 1
#define str(s) s + 1
in the following code
在下面的代码中
#define foo 4
int main()
{
std::cout << str(foo) << '\n'
<< xstr(foo) << '\n' ;
}
it would evaluate like
它会评估像
First string
第一个字符串
- Substitute
str(foo)with<foo-value> + 1, ie4 + 1 - Nothing more to substitute. Finishing.
- 替换
str(foo)为<foo-value> + 1,即4 + 1 - 没有什么可以替代的了。精加工。
And result is 4 + 1
结果是 4 + 1
Second string
第二个字符串
- Substitute
xstr(foo)withstr(<foo-value>) + 1, iestr(4) + 1 - Substitute
str(4)with<4-value> + 1, ie4 + 1 - Nothing more to substitute.
- 替换
xstr(foo)为str(<foo-value>) + 1,即str(4) + 1 - 替换
str(4)为<4-value> + 1,即4 + 1 - 没有什么可以替代的了。
And result is 4 + 1 + 1
结果是 4 + 1 + 1

