2013-06-25 5 views
8

In dem Code, den ich vor kurzem geschrieben habe, habe ich ein seltsames Verhalten bemerkt.make_pair Namespace Verschmutzung

Wenn ich make_pair mit dem ersten Argument ein std::pair zu sein, wird make_pair „magische Weise“ im Namensraum verfügbar

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

Die gerade fein kompiliert (Ich habe keine std:: Qualifier verwenden müssen) (mit -Wall and -pedantic-errors) und Ausgänge:

2 
10 
0 

Warum ist das passiert? Ich habe mich mit cppreference befasst und keinen Hinweis darauf gefunden, dass dieses Verhalten korrekt ist. Fehle ich etwas?

FYI, ich bin mit gcc 4.6.3

+8

[Argument abhängig (a.k.a. Koenig) lookup] (http://en.wikipedia.org/wiki/Argument-dependent_name_lookup). Einige nützliche SO Links/mögliche Duplikate: [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-evented), [3] (http://stackoverflow.com/questions/8111677/detailed-explanation-on-how- koenig-lookup-works-mit-namespaces-und-warum-es-ein-gehen/8111750 # 8111750). – jrok

+0

das war schnell ... danke! –

+0

Gern geschehen, gut geschriebene Frage, übrigens.ADL ist nicht ohne Probleme, das ist eine gute Lektüre: [Was sind die Fallstricke von ADL?] (Http://stackoverflow.com/questions/2958648/what-are-the-pitfalls-of-adl) – jrok

Antwort

22

Das ist ein weniger bekanntes Merkmal von C++, wie @jrok sekundenschnell und wies darauf hin, Koenig Lookup, oder in der modernen C++ 1), ADL (Argumentabhängige Suche). Es sucht im Wesentlichen in Namespaces nach den Argumenten für die Funktion, die Sie aufrufen möchten (make_pair in diesem Beispiel). Das Argument, das die ADL auslöst, ist offensichtlich std::pair.

1) die Namensgebung geändert wurde, obwohl viele Leute das erste Glied wissen


Vielleicht ist es wert zu erwähnen, dass ADL ganz wichtig ist für eine bestimmte Art von Funktionen: Betreiber. Wenn nicht, wäre es sogar für das triviale C++ "Hallo, Welt!" Unmöglich. dies funktioniert, weil:

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

Wäre da dies geschrieben werden müssen:

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

Dank ADL wird << richtig in std Namensraum aufgelöst werden.


Referenzen:

+0

Danke für die Zusammenfassung. –

Verwandte Themen