Açılı ayraçlar da ifade etmektedir (ya da meydana) çünkü karşılaştırma operatörleri <
, >
, <=
ve >=
parantez içinde olduğu gibi, makro genişleme köşeli parantez içinde virgül göz ardı edilemez. (Bu aynı zamanda köşeli parantezler ve kaşlı ayraçlar için de bir sorundur, bunlar genellikle dengeli çiftler olarak görülse de.) Makro bağımsız değişkenini parantez içine alabilirsiniz:
FOO((std::map<int, int>), map_var);
Bu durumda sorun, parametrenin makro genişletme içinde parantez içinde kalması ve bu da çoğu bağlamda bir tür olarak okunmasını engellemesidir.
Bunu geçici olarak çözmenin güzel bir yolu, C ++ 'da, bir işlev türü kullanarak parantezli bir tür adından bir tür adını çıkarabilmenizdir:
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);
İşlev türleri oluşturmak fazladan parantezleri yok saydığından, bu makroyu, tür adının virgül içermediği durumlarda parantezli veya parantezsiz kullanabilirsiniz:
FOO((int), int_var);
FOO(int, int_var2);
C de, elbette, bu gerekli değildir çünkü tür adları parantez dışında virgül içeremez. Yani, diller arası bir makro için şunları yazabilirsiniz:
#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