因为尖括号也可以代表(或发生在)比较运算符<
,>
,<=
和>=
,宏扩展不能像它括号内确实忽略角括号内的逗号。(即使方括号和大括号通常以平衡对出现,这也是方括号和大括号的问题。)您可以将宏参数括在括号中:
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