Tra cứu tên và giải quyết quá tải là khác nhau. Tên phải được tìm thấy trong một phạm vi trước tiên, tức là chúng ta phải tìm một X
tên sao cho tên do_stuff
được phân giải thành X::do_stuff
- độc lập với việc sử dụng tên - và sau đó giải quyết quá tải chọn giữa các khai báo khác nhau X::do_stuff
.
Quá trình KHÔNG xác định tất cả các trường hợp như vậy A::do_stuff
, B::do_stuff
vv có thể nhìn thấy, và sau đó thực hiện giải quyết tình trạng quá tải giữa các công đoàn về điều đó. Thay vào đó, một phạm vi duy nhất phải được xác định cho tên.
Trong mã này:
struct Baz : public Foo, public Bar
{
void func ()
{
do_stuff (1.1f); // ERROR HERE
}
};
Baz
không chứa tên do_stuff
, vì vậy các lớp cơ sở có thể được tra cứu. Nhưng tên xảy ra ở hai cơ sở khác nhau, vì vậy việc tra cứu tên không xác định được phạm vi. Chúng tôi không bao giờ nhận được cho đến khi giải quyết quá tải.
Các sửa chữa được đề xuất trong câu trả lời khác hoạt động vì nó giới thiệu tên do_stuff
cho phạm vi Baz
và cũng giới thiệu 2 quá tải cho tên. Vì vậy, tra cứu tên xác định điều đó do_stuff
có nghĩa là Baz::do_stuff
và sau đó giải quyết quá tải chọn từ hai chức năng được gọi là Baz::do_stuff
.
Như một bên, bóng là một hậu quả khác của tra cứu tên (bản thân nó không phải là một quy tắc). Tra cứu tên chọn phạm vi bên trong và vì vậy mọi thứ trong phạm vi bên ngoài không khớp.
Một yếu tố phức tạp hơn nữa xảy ra khi tra cứu phụ thuộc vào đối số đang diễn ra. Để tóm tắt rất ngắn gọn, việc tra cứu tên được thực hiện nhiều lần cho một lệnh gọi hàm với các đối số của loại lớp - phiên bản cơ bản như được mô tả trong câu trả lời của tôi, và sau đó một lần nữa cho từng loại đối số. Sau đó, sự kết hợp của các phạm vi được tìm thấy đi vào tập hợp quá tải. Nhưng điều đó không áp dụng cho ví dụ của bạn vì hàm của bạn chỉ có các tham số của kiểu dựng sẵn.