20

Đây là câu hỏi phức tạp hơn nêu tại How does overload resolution work when an argument is an overloaded function?Khấu trừ đối số mẫu hoạt động như thế nào khi một hàm quá tải được tham gia như một đối số?

Dưới đây đang compiles without any problem:

void foo() {} 
void foo(int) {} 
void foo(double) {} 
void foo(int, double) {} 

// Uncommenting below line break compilation 
//template<class T> void foo(T) {} 

template<class X, class Y> void bar(void (*f)(X, Y)) 
{ 
    f(X(), Y()); 
} 

int main() 
{ 
    bar(foo); 
} 

Nó không xuất hiện một nhiệm vụ đầy thử thách để khấu trừ mẫu luận - chỉ có một chức năng foo() mà chấp nhận hai lập luận. Tuy nhiên, uncommenting quá tải mẫu của foo() (mà vẫn chỉ có một tham số duy nhất) phá vỡ biên dịch không có lý do rõ ràng. Biên dịch thất bại cả với gcc 5.x/6.x và clang 3.9.

Có thể giải thích bằng các quy tắc về độ phân giải quá tải/khấu trừ đối số mẫu hay nó phải đủ điều kiện như một khiếm khuyết trong các trình biên dịch đó?

+3

này được giải thích bởi phần 13,3 của ++ Chuẩn C;) –

Trả lời

19

Như đã đề cập trong câu trả lời cho câu hỏi liên kết của bạn:

[temp.deduct.call]/6: Khi P là một loại chức năng, con trỏ đến chức năng loại, hoặc con trỏ đến kiểu hàm thành viên:

- Nếu đối số là một tập quá tải chứa một hoặc nhiều mẫu chức năng, tham số được xử lý dưới dạng ngữ cảnh không được suy luận.

Vì tập quá tải chứa mẫu chức năng, tham số được coi là ngữ cảnh không được suy luận. Điều này làm cho mẫu trích lập luận thất bại:

[temp.deduct.type]/4: [...] Nếu một tham số mẫu chỉ được sử dụng trong không suy luận bối cảnh và không được xác định một cách rõ ràng, khấu trừ mẫu đối số thất bại.

Và khoản khấu trừ này không thành công cho bạn lỗi của bạn. Lưu ý rằng nếu bạn chỉ định một cách rõ ràng các đối số, mã biên dịch thành công:

bar<int,double>(foo); 

Live demo

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