我能安全地期待这个
#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)
生成
template < >
template < typename Arg0 >
template < typename Arg0 , typename Arg1 >
template < typename Arg0 , typename Arg1 , typename Arg2 >
在任何合理标准的 C 预处理器上?
我担心的是在上次替换之后连接后的宏扩展:它是否有效,以便在 N 被替换后,例如 2 然后
TEMPLATE_DECL_BEGIN_2
变为
TEMPLATE_DECL_BEGIN_1 , typename Arg1
答案 0 :(得分:3)
是。从C99标准的6.10.3.3§3开始:
对于类似对象和类似函数的宏调用,在替换列表之前 重新检查更多的宏名称来替换,##预处理令牌的每个实例 在替换列表中(不是从参数中)被删除并进行前面的预处理 token与以下预处理标记连接。
和6.10.3.4§3:
替换列表中的所有参数都被替换后#and ## 处理已经发生,所有地标预处理令牌都被删除。然后, 重新扫描生成的预处理标记序列以及所有后续标记序列 预处理源文件的标记,以便更换更多的宏名称。
标准保证x ## y
在替换更多宏名称之前发生,因此如果您在此时构造宏名称,它将被替换。
这是来自C99标准,但我非常怀疑他们是否从C89标准改变了这个版本,C89标准将是真正适用于C ++的版本。