Hãy xem xét các đoạn sau:tra cứu tên phụ thuộc vào chức năng template: kêu vang từ chối, gcc chấp nhận
struct X { };
namespace foo {
template <class T>
void bar() { T{} < T{}; }
void operator<(const X&, const X&) {}
}
int main() {
foo::bar<X>();
}
kêu vang từ chối mã này, gcc chấp nhận nó. Đây có phải là lỗi gcc hay là lỗi này?
Tôi không thấy đó là lỗi vì loại 'T' có thể tham chiếu đến bất kỳ loại nào. Nếu kiểu đó 'T' không quá tải hoặc hỗ trợ toán tử' <'thì hàm' bar' sẽ thất bại. Vì bạn đã quá tải toán tử '<' nên tất cả đều tốt. Tôi đoán nó tất cả đi xuống để làm thế nào trình biên dịch đọc mã, nhưng ngữ nghĩa khôn ngoan nó không phải là dễ bị lỗi. – Poriferous
@ Poriferous Điều đó không có ý nghĩa gì cả. Câu hỏi đặt ra là về hành vi đúng của 'bar()' là cho các kiểu 'T' không có' toán tử <'. Hành vi đúng là: "có, nó tìm' bar :: operator <'" (trong trường hợp này, clang có lỗi) hoặc "mã bị lỗi" (trong trường hợp này, gcc có lỗi). – Barry
Điều đó không có ý nghĩa bởi vì 'bar' là một hàm và không có toán tử' thành viên <'. Vì bạn đã định nghĩa 'toán tử <' cho struct 'X', tôi thực sự không thấy vấn đề là gì ở đây. Ngay cả khi quá tải của toán tử được nhúng trong cấu trúc 'X' thì mã vẫn phải biên dịch chính xác. Để công bằng, đó là tiếng kêu có lỗi kể từ khi nó xuất hiện để giả định một loại là gì. Tôi có nghĩa là, bạn đã thử thay thế 'foo :: thanh()' với một cái gì đó như 'foo :: thanh ()' và xem nếu clang từ chối mã đó quá? –
Poriferous