Comma in C/C++ macro Comma in C/C++ macro c c

Comma in C/C++ macro


If you can't use parentheses and you don't like Mike's SINGLE_ARG solution, just define a COMMA:

#define COMMA ,FOO(std::map<int COMMA int>, map_var);

This also helps if you want to stringify some of the macro arguments, as in

#include <cstdio>#include <map>#include <typeinfo>#define STRV(...) #__VA_ARGS__#define COMMA ,#define FOO(type, bar) bar(STRV(type) \    " has typeid name \"%s\"", typeid(type).name())int main(){    FOO(std::map<int COMMA int>, std::printf);}

which prints std::map<int , int> has typeid name "St3mapIiiSt4lessIiESaISt4pairIKiiEEE".


Because angle brackets can also represent (or occur in) the comparison operators <, >, <= and >=, macro expansion can't ignore commas inside angle brackets like it does within parentheses. (This is also a problem for square brackets and braces, even though those usually occur as balanced pairs.) You can enclose the macro argument in parentheses:

FOO((std::map<int, int>), map_var);

The problem is then that the parameter remains parenthesized inside the macro expansion, which prevents it being read as a type in most contexts.

A nice trick to workaround this is that in C++, you can extract a typename from a parenthesized type name using a 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 nameFOO((std::map<int, int>), map_var);

Because forming function types ignores extra parentheses, you can use this macro with or without parentheses where the type name doesn't include a comma:

FOO((int), int_var);FOO(int, int_var2);

In C, of course, this isn't necessary because type names can't contain commas outside parentheses. 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


If your preprocessor supports variadic macros:

#define SINGLE_ARG(...) __VA_ARGS__#define FOO(type,name) type nameFOO(SINGLE_ARG(std::map<int, int>), map_var);

Otherwise, it's a bit more tedious:

#define SINGLE_ARG2(A,B) A,B#define SINGLE_ARG3(A,B,C) A,B,C// as many as you'll needFOO(SINGLE_ARG2(std::map<int, int>), map_var);