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;
}
};
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
Dzięki Bo. Link do ADL wyjaśnia. – user2023370
@Xeo: Czy nie oznacza to, że wywołanie 'foobar (f)' zawodzi po znalezieniu 'foobar (Bar b)'? – user2023370