เนื่องจากวงเล็บมุมสามารถแสดง (หรือเกิดขึ้นใน) ตัวดำเนินการเปรียบเทียบได้<
เช่น>
กัน<=
และ>=
การขยายมาโครจะไม่สามารถเพิกเฉยต่อเครื่องหมายจุลภาคภายในวงเล็บเหลี่ยมได้เช่นเดียวกับในวงเล็บ (นี่เป็นปัญหาสำหรับวงเล็บเหลี่ยมและวงเล็บปีกกาแม้ว่าโดยปกติจะเกิดเป็นคู่สมดุลก็ตาม) คุณสามารถใส่อาร์กิวเมนต์มาโครไว้ในวงเล็บ:
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);
แน่นอนว่าใน C ไม่จำเป็นเพราะชื่อประเภทต้องไม่มีเครื่องหมายจุลภาคนอกวงเล็บ ดังนั้นสำหรับมาโครข้ามภาษาคุณสามารถเขียน:
#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