Since angle brackets can also represent (or occur) comparison operators < , > , <= and >= , macro expansion cannot ignore commas inside angle brackets, as is done in parentheses. (This is also a problem for square brackets and curly braces, although they usually occur as balanced pairs.) You can enclose the macro argument in parentheses:
FOO((std::map<int, int>), map_var);
The problem is that the parameter remains in brackets inside the macro extension, which prevents it from being read as a type in most contexts.
A good trick to solve this issue is that in C ++ you can extract the type name from the name in brackets using the function type:
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);
Since function type generation ignores extra parentheses, you can use this macro with or without parentheses, where the type name does not contain a comma:
FOO((int), int_var); FOO(int, int_var2);
In C, of course, this is not necessary because type names cannot contain commas outside brackets. So, for a cross-language macro, you can write:
#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