Оскільки кутові дужки можуть також представляти (або відбуваються в) оператори порівняння <
, >
, <=
і >=
, макро розширення не може ігнорувати коми всередині кутові дужки , як це відбувається в круглих дужках. (Це також проблема квадратних дужок і дужок, навіть якщо вони зазвичай бувають врівноваженими парами.) Макро аргумент можна вкласти в круглі дужки:
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);
Звичайно, це не обов'язково, оскільки імена типів не можуть містити коми поза дужок. Отже, для міжмовного макросу ви можете написати:
#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