2015-09-04 17 views
6

Tôi tìm thấy một câu hỏi cho thấy làm thế nào để quá tải macro dựa trên số lượng các đối số: Overloading Macro on Number of Arguments__VA_ARGS__ mở rộng sử dụng MSVC

Nhưng như họ nói, nó không làm việc sử dụng MSVC vì MSVC mở rộng __VA_ARGS__ vào một thẻ duy nhất thay vì một danh sách các đối số (arg1, arg2, arg3).

Họ chỉ vào một câu hỏi khác nơi công việc được đưa ra: MSVC doesn't expand __VA_ARGS__ correctly Nhưng không giải thích chút nào, vì vậy tôi không thể điều chỉnh nó cho trường hợp của riêng mình vì tôi không thể hiểu được.

Bạn có thể giải thích cách giải pháp này hoạt động không?

+0

Tôi nghĩ bài đăng được liên kết không chính xác. Tôi nghĩ rằng các giải pháp đúng là 'G (...) F (EXPAND (__ VA_ARGS__))' – LPs

+0

@ LPs, tôi nghĩ như vậy quá, nhưng hãy thử nó. –

+0

@JohnBollinger Tôi cũng quá Linux bên trong để đưa tay lên MSVC :). Nghiêm túc, tôi đã không có MSVC để kiểm tra nó. Hãy thử dùng thử nó – LPs

Trả lời

9

Cách giải quyết trong câu hỏi là thế này:

#define EXPAND(x) x 
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__ 
#define G(...) EXPAND(F(__VA_ARGS__)) 

Ý tưởng là đưa ra một hiện variadic vĩ mô F():

#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__ 

thay vì viết mong muốn wrapper vĩ mô variadic của bạn như là, trong trường hợp này, ...

#define G(...) F(__VA_ARGS__) 

... bạn viết G() khi sử dụng macro EXPAND() bổ sung. Định nghĩa thực tế của F() không phải là vấn đề, và đặc biệt không quan trọng đối với ví dụ này là việc mở rộng macro không tạo ra mã C hợp lệ. Mục đích của nó là để chứng minh hành vi của tiền xử lý đối với các đối số macro. Cụ thể, nó cho thấy rằng mặc dù MSVC mở rộng __VA_ARGS__ thành một mã thông báo duy nhất trong macro Vĩ mô, có thể làm việc xung quanh bằng cách buộc phải mở rộng gấp đôi.

Ví dụ, bằng cách sử dụng định nghĩa workaround, Preprocessor đầu tiên mở rộng ...

G(1, 2, 3) 

... để ...

EXPAND(F(1, 2, 3)) 

... nơi 1, 2, 3 được coi là một mã thông báo duy nhất. Việc tokenization đó không còn quan trọng khi preprocessor rescans cho các thay thế bổ sung, tuy nhiên: nó nhìn thấy các đối số riêng biệt cho macro F() và mở rộng như mong muốn để tạo đối số cho macro EXPAND(), thay thế nó bằng chính nó.

Nếu bạn cho rằng việc này hoạt động như dự định, nhưng phiên bản không có EXPAND() không hoạt động (trong MSVC), bạn đã đúng.

+0

cảm ơn sự giúp đỡ của bạn! tôi sẽ xem xét điều này sau! – Virus721

+0

Nó hoạt động, cảm ơn. Tôi cũng hiểu nó tốt hơn bây giờ. Gọi macro nơi các đối số được cho là được mở rộng bằng cách sử dụng macro khác làm cho trình biên dịch mở rộng các đối số một cách chính xác. – Virus721

+0

Thực ra trường hợp của tôi hơi khác một chút. Tôi muốn quá tải dựa trên số lượng các đối số: 1 arg -> phương pháp cho 1 arg, 2 args -> phương pháp cho 2 args. NHƯNG: Tôi cũng muốn rằng> 2 args -> phương pháp cho 2 args + và args, kể từ khi hai quá tải cho vĩ mô của tôi có thể có một danh sách arg sau khi các thông số bắt buộc của họ. Điều này gây ra cho tôi một vấn đề, bởi vì khi tôi gọi phương thức của tôi với> 2 args, thì đối số thứ 3 được sử dụng làm tên phương thức, đó là sai. – Virus721

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