Một sử dụng-khai hoạt động như một tuyên bố bình thường: nó che giấu tờ khai phạm vi bên ngoài, nhưng nó không ngăn chặn tra cứu luận phụ thuộc (ADL).
Khi bạn thực hiện using B::f
, về cơ bản bạn không thay đổi gì cả. Bạn chỉ cần redeclare B::f
trong phạm vi địa phương, nơi nó đã được nhìn thấy anyway. Điều đó cũng không ngăn ADL tìm được số A::f
, điều này tạo ra sự mơ hồ giữa A::f
và B::f
.
Nếu bạn làm using A::f
, khai báo địa phương là A::f
sẽ ẩn khai báo ngoài của B::f
. Vì vậy, B::f
không còn hiển thị và không còn tìm thấy bằng tra cứu tên không đủ tiêu chuẩn. Chỉ có A::f
được tìm thấy ngay bây giờ, có nghĩa là không còn mơ hồ nữa.
Không thể chặn ADL. Vì đối số trong trường hợp của bạn là loại
A::X
, chức năng
A::f
sẽ luôn được ADL tìm thấy cho tên không đủ tiêu chuẩn
f
. Bạn không thể "loại trừ" nó khỏi xem xét. Điều đó có nghĩa là bạn không thể mang lại
B::f
vào xem xét mà không tạo ra sự mơ hồ. Cách duy nhất xung quanh là sử dụng tên đủ điều kiện.
Khi @Richard Smith ghi chú chính xác trong các nhận xét, ADL có thể bị chặn. ADL chỉ được sử dụng khi tên hàm chính nó được sử dụng như biểu thức postfix trong lời gọi hàm. Chỉ định hàm mục tiêu theo bất kỳ cách nào khác sẽ kích hoạt ADL.
Ví dụ, khởi tạo của con trỏ hàm là không phụ thuộc vào ADL
void g(A::X x)
{
void (*pf)(A::X) = &f;
pf(x);
}
Trong ví dụ trên B::f
sẽ được gọi. Và thậm chí là một cặp chỉ của ()
xung quanh tên hàm là đủ để ngăn chặn ADL, ví dụ:
void g(A::X x)
{
(f)(x);
}
là đã đủ để làm cho nó gọi B::f
.
Bạn có thể chặn ADL tại trang cuộc gọi bằng cách ngoặc đơn tên hàm. Sử dụng '(f) (x)' sửa chữa sự mơ hồ. –
Rõ ràng 'sử dụng B :: f;' là không cần thiết trong bất kỳ đoạn mã ở trên – Tony