Vui lòng xem xét mã này:SFINAE với các tham số kiểu mảng hoặc kiểu hàm không hợp lệ?
template<typename T>
char (&f(T[1]))[1];
template<typename T>
char (&f(...))[2];
int main() { char c[sizeof(f<void()>(0)) == 2]; }
tôi mong đợi nó làm SFINAE và chosing sự quá tải thứ hai, kể từ khi thay thế T
vào T[1]
sản lượng
void [1]()
Đó là một kiểu không hợp lệ, tất nhiên. Việc điều chỉnh các kiểu tham số (array-> pointer) được thực hiện sau khi thay thế các tham số mẫu thành các tham số hàm và kiểm tra các kiểu kết quả hợp lệ như 14.8.2 [temp.deduct] mô tả.
Nhưng cả Comeau và GCC đều không biên dịch được ở trên. Cả hai đều có chẩn đoán khác nhau.
Comeau nói:
"ComeauTest.c", line 2: error: array of functions is not allowed
char (&f(T[1]))[1];
GCC nói (phiên bản 4.3.3
):
error: ISO C++ forbids zero-size array
c
Ý nghĩa, GCC không thất bại trong việc thay thế, nhưng nó chọn quá tải đầu tiên của f
, trả lại một sizeof
của 1, thay vì không thay thế nó lên phía trước như Comeau.
Trình biên dịch nào là đúng và mã của tôi có hợp lệ không? Vui lòng tham khảo hoặc trích dẫn phần Chuẩn thích hợp trong câu trả lời của bạn. Cảm ơn!
Cập nhật: Các tiêu chuẩn riêng của mình chứa như một ví dụ trong danh sách ở 14.8.2/2
. Tôi không biết tại sao tôi bỏ qua nó lần đầu tiên:
template <class T> int f(T[5]);
int I = f<int>(0);
int j = f<void>(0); // invalid array
Trong khi ví dụ này là chỉ cung cấp thông tin, nó cho thấy ý định của tất cả những đoạn bí ẩn và dường như hiển thị các mã trên nên làm việc và từ chối sự quá tải đầu tiên.
litb yêu cầu làm rõ tiêu chuẩn là mâu thuẫn :) – JaredPar
tôi hỏi tương tự trên usenet, nhưng đăng câu hỏi ở đây quá, để nó có thể được lưu trữ trên SO và mọi người sẽ tìm thấy nó khi tìm kiếm trên SO. Liên kết với usenet: http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/78f8cd8cf27778e3 –
Tôi nghĩ litb LÀ tiêu chuẩn ...? –