2012-08-08 39 views
9

Trong mã C++ bên dưới, foobar được xác định trước cho một tham số double duy nhất, và sau đó một lần nữa cho một tham số đơn loại Foo. Cả hai đều được định nghĩa trong không gian tên chung.Truy cập không gian tên chung C++ từ bên trong một không gian tên khác

Trong không gian tên one, quá tải thêm foobar được xác định, với thông số duy nhất là loại Bar. Từ phiên bản foobar này, cuộc gọi không đủ tiêu chuẩn đến foobar với đối số double (42.0) sẽ không thành công. Một cuộc gọi tương tự như foobar, thời gian này đủ điều kiện với toán tử độ phân giải phạm vi (: :), cũng với đối số double, sẽ thành công.

Mặt khác, một cuộc gọi không đủ tiêu chuẩn đến foobar, với đối số loại Foo, thành công. Một cuộc gọi đến foobar với một đối số Foo, đủ điều kiện bởi nhà điều hành giải pháp phạm vi, cũng thành công.

Tại sao hai trường hợp lại hoạt động khác nhau? Tôi sử dụng cả gcc 4.7 và clang ++ 3.2.

struct Foo {}; 
struct Bar {}; 

double foobar(double x) { return x; } 
Foo foobar(Foo f) { return f; } 

namespace one { 

    Bar foobar(Bar b) { 
    //foobar(42.0); // error: can't convert to Bar 
    ::foobar(42.0); 

    Foo f; 
     foobar(f); // no problem 
    ::foobar(f); 
    return b; 
    } 
}; 

Trả lời

8

Argument dependent lookup.

Trong các cuộc gọi foobar(f) chức năng từ không gian tên Foo sẽ được xem xét.

Không hoạt động cho double vì loại đó không được khai báo trong bất kỳ không gian tên nào.

+0

Ngoài câu cuối cùng: tra cứu tên không đủ tiêu chuẩn sẽ dừng ngay khi tìm thấy tên * phù hợp, trước tiên xem xét phạm vi địa phương và chỉ khi không tìm thấy bất kỳ tên nào ở đó, nó sẽ tìm kiếm phạm vi trên và toàn cầu . – Xeo

+0

Cảm ơn Bo. Các liên kết đến ADL làm cho mọi thứ rõ ràng. – user2023370

+0

@Xeo: Điều đó không ngụ ý rằng lệnh gọi 'foobar (f)' sẽ thất bại khi tìm 'foobar (Bar b)'? – user2023370

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