Karena kurung sudut juga dapat mewakili (atau terjadi pada) operator perbandingan <
, >
, <=
dan >=
, ekspansi makro tidak bisa mengabaikan koma di dalam tanda kurung sudut seperti itu tidak dalam tanda kurung. (Ini juga masalah untuk tanda kurung siku dan tanda kurung siku, meskipun itu biasanya terjadi sebagai pasangan seimbang.) Anda bisa mengapit argumen makro dalam tanda kurung:
FOO((std::map<int, int>), map_var);
Masalahnya adalah bahwa parameter tetap dalam tanda kurung di dalam perluasan makro, yang mencegahnya dibaca sebagai tipe di sebagian besar konteks.
Trik yang bagus untuk mengatasinya adalah bahwa di C ++, Anda dapat mengekstrak nama jenis dari nama jenis dalam tanda kurung menggunakan jenis fungsi:
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);
Karena tipe fungsi pembentuk mengabaikan tanda kurung ekstra, Anda bisa menggunakan makro ini dengan atau tanpa tanda kurung di mana nama tipe tidak menyertakan koma:
FOO((int), int_var);
FOO(int, int_var2);
Di C, tentu saja, ini tidak diperlukan karena nama tipe tidak boleh berisi koma di luar tanda kurung. Jadi, untuk makro lintas bahasa Anda bisa menulis:
#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