2015-04-08 12 views
10

miałem problem w niektórych kodu produkcyjnego że zminimalizowane do następnego testu:Co to jest wyszukiwanie nazw C++? (I jest GCC prawda?)

template<typename T> 
void intermediate(T t) 
{ 
    func(t); // line 4 ("func not declared in this scope") 
} 

namespace ns { 
    struct type {}; 
} 

void func(ns::type const & p); // line 11 ("declared here, later") 

void foo(ns::type exit_node) 
{ 
    intermediate(exit_node); // line 15 ("required from here") 
} 

GCC 4.5 kompiluje tej grzywny. Zarówno z jak i bez -std=c++11, 4,7 i 4,9 generowania komunikatów, takich jak:

test.cpp: In instantiation of ‘void intermediate(T) [with T = ns::type]’: 
test.cpp:15:27: required from here 
test.cpp:4:5: error: ‘func’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] 
test.cpp:11:6: note: ‘void func(const ns::type&)’ declared here, later in the translation unit 

Wszystkie poniższe trzy rzeczy spowoduje, że plik z powodzeniem kompilacji:

  1. Move func(ns::type) do ns nazw (pozwalającej ADL do znaleźć w ns)
  2. Move type do globalnej przestrzeni nazw (ADL pozwala na znalezienie go w ::)
  3. Pozbądź intermediate i nazywają func bezpośrednio od foo

więc ... co tu się dzieje? Czy GCC może odrzucić ten program? Dlaczego func znaleziono przez niewykwalifikowane wyszukiwanie w trzecim wariancie (wywołanie func bezpośrednio z foo), ale nie znaleziono go przez niewykwalifikowane wyszukiwanie w oryginalnym wariancie w punkcie tworzenia?

+0

Powinny być: (&& jest GCC prawe)? – Slava

Odpowiedz

7

Ogólna zasada jest taka, że ​​wszystko, co nie znajduje się w kontekście definicji szablonu, można pobrać tylko przez ADL. Innymi słowy, normalne niewykwalifikowane wyszukiwanie jest wykonywane tylko w kontekście definicji szablonu.

Ponieważ nie deklaracja func jest widoczne, gdy intermediate zdefiniowano i func nie jest w nazw związanego z ns::type jest źle tworzy kod.

+0

Innymi słowy, kandydaci nazywają obiektami docelowymi (i) te znalezione przez niewykwalifikowane wyszukiwanie w punkcie definicji (stąd "zdefiniowana później" notatka) i (ii) te znalezione przez ADL w punkcie stawiania? – EvanED

+0

@ ADLED ADL uwzględnia zarówno kontekst definicji, jak i instancji. –

3

GCC ma rację. func można znaleźć tylko przez ADL, ponieważ jest to niekwalifikowane, zależne wywołanie funkcji. func jest zadeklarowany w globalnej przestrzeni nazw, ale jest to , a nie skojarzona przestrzeń nazw ns::type, tylko ns (dlatego Twój obecny kod nie działa). Po zastąpieniu intermediate(exit_node) bezpośrednim połączeniem z func(exit_node) wewnątrz foo, zostanie znalezione przez normalne niewykwalifikowane wyszukiwanie.