2013-06-25 19 views
8

W kodzie, który ostatnio pisałem, zauważyłem dziwne zachowanie.zanieczyszczenie przestrzeni nazw make_pair

Gdy używam make_pair z pierwszym argumentem bycia std::pair, make_pair staje się „magicznie” dostępne w przestrzeni nazw (nie trzeba używać std:: kwalifikator)

#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; 
} 

kompiluje dobrze (z -Wall and -pedantic-errors) i danych wyjściowych:

2 
10 
0 

Dlaczego tak się dzieje? Sprawdziłem cppreference i nie znalazłem żadnej wskazówki, że to zachowanie jest poprawne. Czy brakuje mi czegoś?

FYI, używam gcc 4.6.3

+8

[Argument dependent (a.k.a. Koenig)] (http://en.wikipedia.org/wiki/Argument-dependent_name_lookup). Kilka przydatnych linków SO/możliwych dups: [1] (http://stackoverflow.com/questions/4886478/functions-with-class-arguments-are-leaked-from-a-amespace/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-with-namespaces-and-why-it-a-go/8111750 # 8111750). – jrok

+0

to było szybko ... dziękuję! –

+0

Nie ma za co, dobrze napisane pytanie, btw.ADL nie jest pozbawiony swoich problemów, jest to dobry odczyt: [Jakie są pułapki ADL?] (Http://stackoverflow.com/questions/2958648/what-are-the-pitfalls-of-adl) – jrok

Odpowiedz

22

To jest mniej znana cecha C++, jak @jrok wskazał niesamowicie szybka, Koenig Lookup lub w nowoczesnych C++ 1), ADL (Argument-Dependent Lookup). To, co robi, polega w zasadzie na wyszukiwaniu w przestrzeni nazw argumentów dla funkcji, którą chcesz wywołać (make_pair w tym przykładzie). Argumentem wyzwalającym ADL jest oczywiście std::pair.

1) nazewnictwo została zmieniona, choć wiele osób wie, pierwszy termin


Być może warto wspomnieć, że ADL jest dość ważne dla jednego konkretnego rodzaju funkcje: operatorów. Gdyby nie to, niemożliwe byłoby nawet trywialne "cześć", świat! do pracy, bo w ten sposób:

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

musiałyby być napisane jak to:

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

Dzięki ADL, << jest prawidłowo rozwiązane być w std nazw.


Referencje:

+0

Dzięki za podsumowanie. –

Powiązane problemy