因为尖括号也可以表示(或出现在)比较运算符<
、和>
,所以宏扩展不能像在括号中那样忽略尖括号内的逗号。(这也是方括号和大括号的问题,即使它们通常作为平衡对出现。)您可以将宏参数括在括号中:<=
>=
FOO((std::map<int, int>), map_var);
问题是该参数在宏扩展内保持括号括起来,这会阻止它在大多数情况下被读取为类型。
解决此问题的一个好技巧是,在 C++ 中,您可以使用函数类型从带括号的类型名称中提取类型名称:
template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };
#define FOO(t,name) argument_type<void(t)>::type name
FOO((std::map<int, int>), map_var);
因为形成函数类型会忽略额外的括号,所以您可以在类型名称不包含逗号的情况下使用带或不带括号的宏:
FOO((int), int_var);
FOO(int, int_var2);
当然,在 C 中,这不是必需的,因为类型名称不能包含括号外的逗号。因此,对于跨语言宏,您可以编写:
#ifdef __cplusplus__
template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };
#define FOO(t,name) argument_type<void(t)>::type name
#else
#define FOO(t,name) t name
#endif