2013-06-25 8 views
8

Nel codice che ho scritto di recente, ho notato uno strano comportamento.make_pair namespace pollution

Quando uso make_pair con il primo argomento ad essere un std::pair, make_pair diventa "magicamente" a disposizione nello spazio dei nomi (non è necessario utilizzare un qualificatore 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; 
} 

Il compila bene (con -Wall and -pedantic-errors) e le uscite:

2 
10 
0 

Perché succede questo? Ho esaminato cppreference e non ho trovato alcun accenno al corretto comportamento di questo comportamento. Mi sto perdendo qualcosa?

FYI, sto usando gcc 4.6.3

+8

[Argomento dipendente (a.k.a. Koenig) lookup] (http://en.wikipedia.org/wiki/Argument-dependent_name_lookup). Alcuni link SO utili/possibili duplicati: [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-with-spazi dei nomi-e-perché-proprio-a-go/8.111.750 # 8.111.750). – jrok

+0

è stato veloce ... grazie! –

+0

Prego, domanda ben scritta, btw.ADL non è privo di problemi, questa è una buona lettura: [Quali sono le insidie ​​di ADL?] (Http://stackoverflow.com/questions/2958648/what-are-the-pitfalls-of-adl) – jrok

risposta

22

Questo è una caratteristica meno nota di C++, come @jrok sottolineato incredibilmente veloce, Koenig Lookup, o nella moderna C++ 1), ADL (Ricerca dipendente dall'argomento). Quello che fa è fondamentalmente la ricerca in namespace degli argomenti per la funzione che si desidera chiamare (make_pair in questo esempio). L'argomento che attiva l'ADL è ovviamente std::pair.

1) la denominazione è stata cambiata, anche se un sacco di gente sa il primo termine


Forse vale la pena ricordare che l'ADL è molto importante per un particolare tipo di funzioni: operatori. Se non fosse così, sarebbe impossibile persino il banale C++ "ciao, mondo!" al lavoro, perché questo:

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

avrebbe dovuto essere scritto come questo:

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

Grazie a ADL, << viene correttamente risolto di essere in std namespace.


Riferimenti:

+0

Grazie per il riassunto. –