Bởi vì dấu ngoặc nhọn cũng có thể đại diện (hoặc xảy ra trong) các toán tử so sánh <
, >
, <=
và >=
, mở rộng vĩ mô không thể bỏ qua dấu phẩy bên trong dấu ngoặc nhọn như nó trong dấu ngoặc đơn. (Đây cũng là vấn đề đối với dấu ngoặc vuông và dấu ngoặc nhọn, mặc dù chúng thường xảy ra dưới dạng các cặp cân bằng.) Bạn có thể đặt đối số macro trong dấu ngoặc đơn:
FOO((std::map<int, int>), map_var);
Vấn đề là sau đó, tham số vẫn được đặt trong ngoặc đơn bên trong phần mở rộng macro, điều này ngăn nó được đọc như một kiểu trong hầu hết các ngữ cảnh.
Một mẹo hay để giải quyết vấn đề này là trong C ++, bạn có thể trích xuất một tên kiểu từ tên kiểu trong ngoặc đơn bằng cách sử dụng kiểu hàm:
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);
Bởi vì việc tạo kiểu hàm bỏ qua dấu ngoặc đơn, bạn có thể sử dụng macro này có hoặc không có dấu ngoặc đơn trong đó tên kiểu không bao gồm dấu phẩy:
FOO((int), int_var);
FOO(int, int_var2);
Tất nhiên, trong C, điều này không cần thiết vì tên kiểu không thể chứa dấu phẩy bên ngoài dấu ngoặc đơn. Vì vậy, đối với macro đa ngôn ngữ, bạn có thể viết:
#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