2013-06-25 49 views
8

Trong đoạn mã tôi đã viết gần đây, tôi đã nhận thấy một hành vi lạ.make_pair ô nhiễm không gian tên

Khi tôi sử dụng make_pair với đối số đầu tiên là một std::pair, make_pair trở thành "kỳ diệu" có sẵn trong không gian tên (Tôi không cần phải sử dụng một vòng std::)

#include <iostream> 

int main() 
{ 
    int i1 = 2; int i2 = 10; int i3 = 0; 

    // constructing a pair using std::make_pair, everything's okay 
    std::pair<int,int> key = std::make_pair(i1, i2); 

    // here, why is make_pair suddenly magically available without the 
    // std:: namespace qualifier? 
    // At the same time, using ::make_pair yields and error 
    // (make_pair has not declared...) 
    std::pair<std::pair<int,int>, int> mypair = make_pair(key, i3); 

    std::cout << mypair.first.first << "\n"; 
    std::cout << mypair.first.second << "\n"; 
    std::cout << mypair.second << "\n"; 

    return 0; 
} 

Các biên dịch tốt (với -Wall and -pedantic-errors) và kết quả đầu ra:

2 
10 
0 

Tại sao điều này xảy ra? Tôi đã nhìn vào cppreference và không tìm thấy bất kỳ gợi ý của hành vi này là chính xác. Tôi có thiếu gì không?

FYI, tôi đang sử dụng gcc 4.6.3

+8

[Phụ thuộc vào đối số (a.k.a. Koenig) tra cứu] (http://en.wikipedia.org/wiki/Argument-dependent_name_lookup). Một số liên kết SO hữu ích/dups có thể: [1] (http://stackoverflow.com/questions/4886478/functions-with-class-arguments-are-leaked-from-a-namespace/4886535#4886535), [2] (http://stackoverflow.com/questions/4276772/why-was-argument-dependent-lookup-invented), [3] (http://stackoverflow.com/questions/8111677/detailed-explanation-on-how- koenig-lookup-works-với-namespaces-và-why-its-a-go/8111750 # 8111750). – jrok

+0

nhanh ... cảm ơn bạn! –

+0

Bạn được chào đón, cũng bằng văn bản câu hỏi, btw.ADL không phải là không có vấn đề của nó, đây là một đọc tốt: [những cạm bẫy của ADL là gì?] (Http://stackoverflow.com/questions/2958648/what-are-the-pitfalls-of-adl) – jrok

Trả lời

22

Đó là một tính năng ít được biết đến của C++, như @jrok chỉ ra tốc độ nhanh, Koenig Lookup, hoặc trong C++ hiện đại 1), ADL (Truy vấn phụ thuộc đối số). Những gì nó làm là cơ bản tìm kiếm trong không gian tên của các đối số cho hàm mà bạn muốn gọi (make_pair trong ví dụ này). Đối số kích hoạt ADL rõ ràng là std::pair.

1) việc đặt tên đã được thay đổi, mặc dù có rất nhiều người biết nhiệm kỳ đầu tiên


Có lẽ đó là đáng nói đến là ADL là khá quan trọng đối với một loại hình cụ thể của các chức năng: nhà khai thác. Nếu không cho nó, nó sẽ là không thể cho ngay cả những C++ tầm thường "hello, thế giới!" để làm việc, bởi vì đây:

std::cout << "Hello, world!"; 

sẽ phải được viết như thế này:

std::operator<< (std::cout, "Hello, world!"); 

Nhờ ADL, << là đúng cách giải quyết được trong std namespace.


Tài liệu tham khảo:

+0

Cảm ơn Tóm tắt. –