2010-08-25 44 views
7

Cân nhắc macro này:macro variadic với zero đối số, và dấu phẩy

#define MAKE_TEMPLATE(...) template <typename T, __VA_ARGS__ > 

Khi sử dụng với zero lập luận nó tạo ra mã xấu kể từ khi biên dịch hy vọng một định danh sau dấu phẩy. Trên thực tế, bộ tiền xử lý của VC đủ thông minh để loại bỏ dấu phẩy, nhưng GCC thì không. Kể từ macro không thể bị quá tải, nó có vẻ như phải mất một macro riêng biệt đối với trường hợp đặc biệt này để làm cho nó đúng, như trong:

#define MAKE_TEMPLATE_Z() template <typename T> 

Có cách nào để làm cho nó làm việc mà không giới thiệu vĩ mô thứ hai?

Trả lời

9

Không, vì lệnh gọi macro MAKE_TEMPLATE() không có đối số bằng 0; nó có một đối số bao gồm các mã thông báo không.

Bộ tiền xử lý cũ hơn, rõ ràng bao gồm GCC tại thời điểm câu trả lời ban đầu được viết, đôi khi diễn giải danh sách đối số trống như bạn mong muốn, nhưng sự đồng thuận đã chuyển sang một phần mở rộng hẹp hơn, chặt chẽ hơn tuân thủ chặt chẽ với tiêu chuẩn.

Để có được câu trả lời dưới đây để làm việc, xác định một tham số vĩ mô bổ sung trước ellipsis:

#define MAKE_TEMPLATE(UNUSED, ...) template <typename T, ## __VA_ARGS__ > 

và sau đó luôn luôn đặt một dấu phẩy trước đối số đầu tiên khi danh sách là không rỗng:

MAKE_TEMPLATE(, foo) 

Câu trả lời cũ

Theo http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html, GCC hỗ trợ điều này, không minh bạch.

Cú pháp là:

#define MAKE_TEMPLATE(...) template <typename T, ## __VA_ARGS__ > 

Dù sao, cả hai cũng hỗ trợ các mẫu variadic trong chế độ C++ 0x, mà còn lâu mới thích hợp hơn.

+0

Cảm ơn. btw, là hành vi tiêu chuẩn này, hay một điều gcc? – uj2

+1

@ uj2: Đó là GCC; tiêu chuẩn chỉ đơn giản là cấm danh sách variadic trống. Bằng cách này, điều này là trộn C99 với C++ anyway, vì vậy mã này là đúng tiêu chuẩn, trừ khi bạn đang ở trong C++ 0x ... trong trường hợp bạn nên ... – Potatoswatter

+0

Đừng bận tâm các mẫu, nó chỉ là một ví dụ đồ chơi. Làm thế nào là điều này nhất thiết phải 0x, không C++ 98/03 xác định các macro variadic? – uj2

1

Trong trường hợp của GCC bạn cần phải viết nó như thế này:

#define MAKE_TEMPLATE(...) template <typename T, ##__VA_ARGS__ > 

Nếu __VA_ARGS__ là trống rỗng, tiền xử lý của GCC xóa bỏ trước dấu phẩy.

0

Trước hết hãy cẩn thận rằng các macro Vĩ mô không phải là một phần của C++ hiện tại. Có vẻ như họ sẽ ở phiên bản tiếp theo. Tại thời điểm này, họ chỉ phù hợp nếu bạn lập trình trong C99.

Kể từ các macro Variad với các đối số bằng không, có các thủ thuật để tăng khả năng phát hiện điều này và chương trình macro xung quanh nó. Googel cho empty macro arguments.

Các vấn đề liên quan