2017-03-10 18 views
9
#include <iostream> 
using namespace std; 

template<typename T> 
void adl(T) 
{ 
    cout << "T"; 
} 

struct S 
{ 
}; 

template<typename T> 
void call_adl(T t) 
{ 
    adl(S()); 
    adl(t); 
} 

void adl(S) 
{ 
    cout << "S"; 
} 

int main() 
{ 
    call_adl(S()); 
} 

Dlaczego wynik to "TS"? Jaka jest reguła wyszukiwania nazw wewnątrz funkcji szablonu?Reguły wyszukiwania nazw w funkcji szablonu

http://ideone.com/sB3DnL

Odpowiedz

9

szablony są zestawiane w dwóch etapach, w momencie określania i punktu instancji. Pierwsza faza ma miejsce, gdy definicja szablonu jest najpierw przetwarzana przez kompilator, a niektóre nazwy są natychmiast wiązane z definicjami. Niektóre nazwy pozostają niezwiązane, dopóki nie zostanie utworzony szablon, ponieważ zależą one od parametrów szablonu i dlatego nie można ich wyszukać, dopóki nie zostanie utworzony szablon, a argumenty szablonu będą znane.

W tej rozmowy:

adl(S()); 

Nic nie jest zależną na parametry szablonu z funkcji, dzięki czemu wyszukiwanie odbywa się od razu (w pierwszej fazie) i stwierdzi, jedyną funkcją o nazwie adl, która jest w tym momencie dostępna.

W tej rozmowy:

adl(t); 

to zależny od rodzaju t i tak odnośnika jest opóźnione aż instancji, gdy rodzaj t jest znana. Podczas wywoływania call_adl(S()) drugie przeciążenie adl jest w zakresie, a więc gdy wywołanie adl(t) wykonuje wyszukiwanie nazw, istnieje inna funkcja w zakresie i jest lepiej dopasowana do argumentów.

+0

A zatem definicja "void adl (S)" nie jest widoczna dla kompilatora w fazie I? – q0987

+0

@ q0987 Nie, ponieważ jest zadeklarowany między definicją i instancją 'call_adl'. – user1937198

+0

@ user1937198, po tym jak przeniosłem "void adl (S)" poniżej funkcji "głównej". Rezultatem jest nadal "TS". Innymi słowy, w momencie tworzenia, "void adl (S)" jeszcze nie jest w zasięgu. to dlaczego wynikiem jest "TS"? http://ideone.com/BApxuL – q0987

Powiązane problemy