2012-08-08 15 views
9

W poniższym kodzie C++ foobar definiuje się najpierw dla pojedynczego parametru double, a następnie ponownie dla pojedynczego parametru typu Foo. Oba są zdefiniowane w globalnej przestrzeni nazw.Dostęp do globalnej przestrzeni nazw C++ z innej przestrzeni nazw

W przestrzeni nazw one zdefiniowano kolejne przeciążenie foobar, z pojedynczym parametrem typu Bar. Od tej wersji foobar, niewykwalifikowane połączenie z foobar z argumentem double (42.0) zakończy się niepowodzeniem. Podobne wywołanie do foobar, tym razem zakwalifikowane za pomocą operatora rozstrzygania zasięgu (: :), również z argumentem double, zakończy się pomyślnie.

Z drugiej strony, niewykwalifikowane połączenie z numerem foobar z argumentem typu Foo powiedzie się. Połączenie z foobar z argumentem Foo, zakwalifikowane przez operatora rozdzielczości, również się powiedzie.

Dlaczego te dwa scenariusze zachowują się inaczej? Używam zarówno gcc 4.7 jak i clang ++ 3.2.

struct Foo {}; 
struct Bar {}; 

double foobar(double x) { return x; } 
Foo foobar(Foo f) { return f; } 

namespace one { 

    Bar foobar(Bar b) { 
    //foobar(42.0); // error: can't convert to Bar 
    ::foobar(42.0); 

    Foo f; 
     foobar(f); // no problem 
    ::foobar(f); 
    return b; 
    } 
}; 

Odpowiedz

8

Argument dependent lookup.

W wywołaniu foobar(f) będą rozpatrywane funkcje z przestrzeni nazw Foo.

Nie działa dla double, ponieważ ten typ nie jest zadeklarowany w żadnej przestrzeni nazw.

+0

Jako uzupełnienie ostatniego zdania: Wyszukiwanie niewykwalifikowanych nazw kończy się, gdy tylko znajdzie pasującą * nazwę *, najpierw biorąc pod uwagę zakresy lokalne i tylko, jeśli nie znajdzie tam żadnej nazwy, przeszuka zakres górny i globalny . – Xeo

+0

Dzięki Bo. Link do ADL wyjaśnia. – user2023370

+0

@Xeo: Czy nie oznacza to, że wywołanie 'foobar (f)' zawodzi po znalezieniu 'foobar (Bar b)'? – user2023370

Powiązane problemy