Mic*_*ung 4 c++ c-preprocessor
我有一个可变参数宏M,它接受由特殊参数分隔的多个参数SEPARATOR:
M(a, b, c, SEPARATOR, 1, 2, 3);\nRun Code Online (Sandbox Code Playgroud)\n我\xe2\x80\x99d 喜欢有两个宏BEFORE,AFTER我可以使用所有M\xe2\x80\x99s 参数进行调用,并且只会分别返回左侧/右侧的参数SEPARATOR。
这意味着BEFORE(a, b, c, SEPARATOR, 1, 2, 3)应该评估为a, b, c,而AFTER(a, b, c, SEPARATOR, 1, 2, 3)应该评估为1, 2, 3。
基于http://jhnet.co.uk/articles/cpp_magic, I\xe2\x80\x99ve 提出了一个适用于上面给出的示例 I\xe2\x80\x99ve 的解决方案:
\nM(a, b, c, SEPARATOR, 1, 2, 3);\nRun Code Online (Sandbox Code Playgroud)\n然而,此解决方案存在一个问题:如果宏参数之一以预处理器标记(例如[in )开头,则会中断M([[maybe_unused]] int a, foo(), SEPARATOR, "abc")。
原因如下:IS_SEPARATOR如果宏的参数以类似于 的标记开头,则宏不会\xe2\x80\x99 工作,因为它尝试将该标记与, (在)中[连接。这是不允许的,并且会生成以下错误:_PROBE_IS_SEPARATOR([[maybe_unused]] int a)
error: pasting "_PROBE_" and "[" does not give a valid preprocessing token\nRun Code Online (Sandbox Code Playgroud)\n您知道IS_SEPARATOR在这种情况下我该如何解决工作吗?或者另一种解决方案如何实现BEFORE和AFTER宏?
编辑: \n要重现该错误,您可以将上述所有内容放入一个文件中,macros.cpp并添加以下行和虚拟实现M(这不会评估为有效的程序,我的实际实现更复杂,但这并不\xe2 \x80\x99 这里并不重要,因为我的目标是暂时修复预处理器步骤):
#define M(...) BEFORE(__VA_ARGS__) && AFTER(__VA_ARGS__)\nM([[maybe_unused]] int a, foo(), SEPARATOR, "abc")\nRun Code Online (Sandbox Code Playgroud)\n然后运行预处理器:
\ng++ -E -P macros.cpp -std=c++17\nRun Code Online (Sandbox Code Playgroud)\nI\xe2\x80\x99d 希望看到的输出是:
\n[[maybe_unused]] int a , foo() && "abc"\nRun Code Online (Sandbox Code Playgroud)\n相反,我们得到了上述错误。
\n如果你这样做,事情就会变得非常容易#define SEPARATOR )(:
#define SEPARATOR )(
#define BEFORE(...) BEFORE_1((__VA_ARGS__))
#define BEFORE_1(...) BEFORE_2 __VA_ARGS__ )
#define BEFORE_2(...) __VA_ARGS__ NULL(
#define NULL(...)
#define AFTER(...) AFTER_1((__VA_ARGS__))
#define AFTER_1(...) AFTER_2 __VA_ARGS__
#define AFTER_2(...) AFTER_3
#define AFTER_3(...) __VA_ARGS__
BEFORE(a, b, c, SEPARATOR, 1, 2, 3) // a,b,c,
AFTER(a, b, c, SEPARATOR, 1, 2, 3) // ,1,2,3
Run Code Online (Sandbox Code Playgroud)
这会将前后的逗号粘贴SEPARATOR到输出中,但处理这个问题留给读者作为练习(也许只需更改语法以删除逗号?)。
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |