宏串联和进一步扩展

发布于 2024-10-15 23:17:14 字数 862 浏览 1 评论 0原文

我可以放心地期望它

#define TEMPLATE_DECL_BEGIN_0 template <
#define TEMPLATE_DECL_BEGIN_1 TEMPLATE_DECL_BEGIN_0 typename Arg0
#define TEMPLATE_DECL_BEGIN_2 TEMPLATE_DECL_BEGIN_1 , typename Arg1
#define TEMPLATE_DECL_BEGIN_3 TEMPLATE_DECL_BEGIN_2 , typename Arg2
#define TEMPLATE_DECL(N) TEMPLATE_DECL_BEGIN_ ## N >

TEMPLATE_DECL(0)
TEMPLATE_DECL(1)
TEMPLATE_DECL(2)
TEMPLATE_DECL(3)

在任何合理标准的 C 预处理器上生成吗

template < >
template < typename Arg0 >
template < typename Arg0 , typename Arg1 >
template < typename Arg0 , typename Arg1 , typename Arg2 >

我担心的是先前替换后串联后的宏扩展:它是否有效,以便在 N 被替换后例如被 2 然后

TEMPLATE_DECL_BEGIN_2

变成

TEMPLATE_DECL_BEGIN_1 , typename Arg1

Can I safely expect this

#define TEMPLATE_DECL_BEGIN_0 template <
#define TEMPLATE_DECL_BEGIN_1 TEMPLATE_DECL_BEGIN_0 typename Arg0
#define TEMPLATE_DECL_BEGIN_2 TEMPLATE_DECL_BEGIN_1 , typename Arg1
#define TEMPLATE_DECL_BEGIN_3 TEMPLATE_DECL_BEGIN_2 , typename Arg2
#define TEMPLATE_DECL(N) TEMPLATE_DECL_BEGIN_ ## N >

TEMPLATE_DECL(0)
TEMPLATE_DECL(1)
TEMPLATE_DECL(2)
TEMPLATE_DECL(3)

to generate

template < >
template < typename Arg0 >
template < typename Arg0 , typename Arg1 >
template < typename Arg0 , typename Arg1 , typename Arg2 >

on any reasonably standard C preprocessor?

My worry is about macro expansion after concatenation after previous replacement: does it work so that after N gets replaced for example by 2 then

TEMPLATE_DECL_BEGIN_2

becomes

TEMPLATE_DECL_BEGIN_1 , typename Arg1

?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄人书 2024-10-22 23:17:14

是的。来自 C99 标准的 6.10.3.3§3:

对于类似对象和类似函数的宏调用,在替换列表之前
重新检查更多宏名称以替换 ## 预处理标记的每个实例
替换列表中(不是来自参数)被删除,并且前面的预处理
令牌与以下预处理令牌连接。

和 6.10.3.4§3 :

替换列表中的所有参数都被替换后#和##
处理完成后,所有地标预处理标记都会被删除。然后,
重新扫描生成的预处理令牌序列以及所有后续的
预处理源文件的标记,以替换更多宏名称。

该标准保证 x ## y 在替换更多宏名称之前发生,因此如果您当时构造一个宏名称,它将被替换。

这是来自 C99 标准,但我非常怀疑他们从 C89 标准更改了这一部分,这将是真正适用于 C++ 的版本。

Yes. From 6.10.3.3§3 of the C99 standard:

For both object-like and function-like macro invocations, before the replacement list is
reexamined for more macro names to replace, each instance of a ## preprocessing token
in the replacement list (not from an argument) is deleted and the preceding preprocessing
token is concatenated with the following preprocessing token.

And 6.10.3.4§3 :

After all parameters in the replacement list have been substituted and #and ##
processing has taken place, all placemarker preprocessing tokens are removed. Then, the
resulting preprocessing token sequence is rescanned, along with all subsequent
preprocessing tokens of the source file, for more macro names to replace.

The standard guarantees that x ## y happens before replacing more macro names, so if you construct a macro name at that time, it will be replaced.

This is from the C99 standard, but I highly doubt they changed this secion from the C89 standard, which would be the version that really applies to C++.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文