2013-01-05 5 views
6

Ho difficoltà a capire le regole dietro la ricerca dipendente da argomenti (Koenig).Ricerca dipendente da argomenti: quando viene eseguita la ricerca e in che modo è possibile forzarla (o impedirla)?

Si consideri il codice qui sotto:

#include <iostream> 

using namespace std; 

namespace adl 
{ 
    struct Test { }; 
    void foo1(Test const &) { cout << "ADL used (foo1)" << endl; } 
    void foo2(Test const &) { cout << "ADL used (foo2)" << endl; } 
    void foo3(Test const &) { cout << "ADL used (foo3)" << endl; } 
} 

struct foo1 
{ 
    foo1() { } 

    template<class T> 
    foo1(T const &) { cout << "ADL not used (foo1)" << endl; } 

    template<class T> 
    void operator()(T const &) const { cout << "ADL not used (foo3)" << endl; } 
}; 

template<class T> void foo2(T const &) 
{ cout << "ADL not used (foo2)" << endl; } 

int main() 
{ 
    adl::Test t; 
    foo1 foo3; 
    (foo1(t)); 
    (foo2(t)); 
    (foo3(t)); 
} 

La sua uscita è:

ADL non utilizzato (foo1)
ADL utilizzato (foo2)
ADL non utilizzato (foo3)

I e li ho osservati tutti per usare ADL, ma sono rimasto sorpreso che solo alcuni di loro l'abbiano fatto.

Quali sono i (potenzialmente cruenti, lo so) dettagli dietro le regole di ADL?
Capisco abbastanza bene il concetto, ma i dettagli sono ciò che sto avendo problemi con.

Quali ambiti vengono cercati, quando vengono cercati e quando non vengono cercati?

E 'del tutto possibile dire se ADL viene utilizzato senza dover guardare attraverso tutti i #include 'd file prima linea data di codice? Mi aspettavo che i funtori e le funzioni si comportassero allo stesso modo in termini di ADL mascherante, ma a quanto pare non lo fanno.

C'è un modo per forza ADL nei casi in cui non viene eseguito automaticamente (come sopra) e non si conosce lo spazio dei nomi della classe (ad esempio in un modello)?

+1

-1 Questa domanda è troppo ampia e l'esempio di codice fa davvero schifo (con nomi fuorvianti, ecc.). –

+1

Non capisco. Perché stai sperimentando con '(foo3 (t));'? Non esiste una funzione chiamata 'foo3'. Quindi ADL non entra in scena. 'foo3' sarà trattato come oggetto, senza alcun dubbio, perché è quello che è (il che significa che chiamerà l'operatore') senza alcun dubbio)! Sono solo nomi fuorvianti che hai usato nel tuo esempio. – Nawaz

+0

@ Cheersandhth.-Alf: Ma non c'è confusione su '(foo3 (t));'. È solo che ha usato nomi fuorvianti per la variabile! – Nawaz

risposta

5

Il tuo problema non è proprio nella ricerca dipendente dall'argomento. Prima di tutto, solo la ricerca dipendente dall'argomento entra possibilmente nell'immagine quando si effettua una ricerca non qualificata delle funzioni. Quando si chiama foo1(t)foo1 è un tipo e viene chiamato il relativo costruttore con modello. Allo stesso modo, foo3(t) è una ricerca qualificata poiché foo3 è un oggetto e l'operatore di chiamata di funzione viene ricercato nella classe dell'oggetto foo1. L'unico posto dove ricerca argomento entra in scena sta chiamando foo2(t) dove lookup trova ai candidati:

  1. ::foo2<adl::Test>(adl::Test const&)
  2. ::adl::foo2(adl::Test const&)

Queste due funzioni sono consegnati fuori sovraccaricare risoluzione e dal momento che entrambe le funzioni sono ugualmente buona corrispondenza vince la funzione non modello.

La tua domanda sono in realtà tre domande:

  1. dettagli scabrosi di ricerca dei nomi sono troppo ampio e, in tal modo, a questa domanda è una richiesta di un saggio da scrivere che io ignoro.
  2. La seconda domanda espande per altre tre domande, solo una sembra pertinente:
    1. Quali ambiti vengono cercati? Quando si cerca un nome di funzione non qualificato all'interno di una definizione di funzione, le regole dipendono dal fatto che uno qualsiasi dei nomi sia un nome dipendente. Se non esiste tale nome (cioè, nel codice non modello o nel codice modello in cui i nomi possono essere determinati nella fase uno), il nome viene cercato includendo spazi dei nomi e in spazi dei nomi associati al suo argomento. Altrimenti, il nome viene cercato solo negli spazi dei nomi associati.
  3. La ricerca dipendente dall'argomento può essere forzata? È sempre fatto per ricerche di funzioni non qualificate se c'è almeno un argomento, ma i nomi trovati in modo diverso potrebbero essere corrispondenze migliori. Naturalmente, è necessario chiamare una funzione non qualificata altrimenti non verrà eseguita.
+0

Ancora cercando di capire cosa rende una chiamata "non qualificata". Pensavo che "non qualificato" significasse "senza qualificatore [cioè spazio dei nomi] menzionato" ... ma apparentemente non è il caso, dal momento che nessuno di questi menziona gli spazi dei nomi? Cosa significa per una chiamata essere non qualificata? – Mehrdad

+0

Quando i nomi vengono cercati, prima registra il nome e si ferma quando viene trovato il nome. 'foo1' trova un tipo e cerca il costruttore da chiamare nel contesto del tipo. Poiché un tipo è stato trovato prima di una funzione, non vengono presi in considerazione altri spazi dei nomi. Allo stesso modo per 'foo3' che si trova essere un oggetto per il quale l'operatore di chiamata di funzione viene cercato nel cintext del tipo dell'oggetto. Per 'foo2' viene trovata una funzione e la chiamata non è qualificata, cioè, i namespace associati agli argomenti vengono cercati per aumentare il set di sovraccarico. –

+0

Questa è una buona descrizione della * procedura * seguita dal compilatore, ma ancora non capisco cosa significhi "qualificato". Sembra che tu definisca la qualifica come "qualunque sia la chiamata che causa ADL", e poi dici che ADL è fatto solo per chiamate non qualificate ... il che è vero per definizione, ma non mi aiuta a capire cosa qualifica una chiamata. Ma cosa rende una chiamata qualificata, esattamente? Come posso sapere se una determinata chiamata è o meno qualificata? – Mehrdad

Problemi correlati