Ponieważ wsporniki kątowe może także oznaczać (lub występują w) operatorów porównania <
, >
, <=
i >=
, makro rozszerzeń nie ignorować przecinki wewnątrz wsporników kątowych, jak to czyni w nawiasach. (Jest to również problem w przypadku nawiasów kwadratowych i nawiasów klamrowych, mimo że zwykle występują one jako zrównoważone pary). Możesz umieścić argument makro w nawiasach:
FOO((std::map<int, int>), map_var);
Problem polega na tym, że parametr pozostaje w nawiasach wewnątrz rozwinięcia makra, co uniemożliwia odczytanie go jako typu w większości kontekstów.
Fajną sztuczką do obejścia tego jest to, że w C ++ możesz wyodrębnić nazwę typu z nazwy typu w nawiasach za pomocą typu funkcji:
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);
Ponieważ tworzenie typów funkcji ignoruje dodatkowe nawiasy, możesz użyć tego makra z nawiasami lub bez, gdzie nazwa typu nie zawiera przecinka:
FOO((int), int_var);
FOO(int, int_var2);
W C oczywiście nie jest to konieczne, ponieważ nazwy typów nie mogą zawierać przecinków poza nawiasami. Tak więc dla makra międzyjęzykowego możesz napisać:
#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