Dlaczego B :: f nie rozwiązuje dwuznaczności, ale A :: f nie?Dlaczego B :: f nie rozwiązuje dwuznaczności, ale A :: f nie?
Odpowiedz
Deklaracja użycia służy jako zwykła deklaracja: ukrywa deklaracje zakresu zewnętrznego, ale nie eliminuje wyszukiwania zależnego od argumentów (ADL).
Po dokonaniu using B::f
zasadniczo nic nie zmieniasz. Po prostu redeclare B::f
w zasięgu lokalnym, gdzie i tak było już widoczne. To nie przeszkadza również ADL w znalezieniu A::f
, co powoduje niejasności między A::f
i B::f
.
Jeśli wykonasz using A::f
, lokalna deklaracja A::f
ukrywa zewnętrzną deklarację B::f
. Tak więc B::f
nie jest już widoczny i nie można go już znaleźć przez niewykwalifikowane wyszukiwanie nazwy. Teraz znajduje się tylko A::f
, co oznacza, że nie ma już niejasności.
Nie można wyłączyć ADL. Ponieważ argument w twoim przypadku jest typu
A::X
, funkcja ADL zawsze znajdzie funkcję
A::f
dla niekwalifikowanej nazwy
f
. Nie można go "wykluczyć" z rozważania. Oznacza to, że nie można wziąć pod uwagę
B::f
bez wywoływania niejednoznaczności. Jedynym sposobem jest użycie kwalifikowanej nazwy.
Jak słusznie zauważył @ Richich Smith w komentarzach, ADL może zostać wyłączony. ADL jest używany tylko wtedy, gdy sama nazwa funkcji jest używana jako wyrażenie Postfiks w wywołaniu funkcji. Określenie funkcji celu w jakikolwiek inny sposób przerazi ADL.
Na przykład inicjalizacji wskaźnika funkcji nie podlega ADL
void g(A::X x)
{
void (*pf)(A::X) = &f;
pf(x);
}
W powyższym przykładzie B::f
zostanie wywołana. A nawet sama para ()
wokół nazwy funkcji jest wystarczająca, aby stłumić ADL, tj
void g(A::X x)
{
(f)(x);
}
wystarcza już, aby zadzwonić B::f
.
Powinieneś napisać przestrzeń nazw za każdym razem jawnie. Wystarczy zrobić
#include <iostream>
namespace A
{
class X { };
void f(X) {
std::cout << "A";
}
}
namespace B
{
void f(A::X) {
std::cout << "B";
}
void g(A::X x)
{
// using B::f;
B::f(x);
}
}
int main() {
B::g(A::X()); // outputs B
}
tak: ...i nigdy nie używaj "namespace xxx" - tylko zasłania i tworzy nieprzyjemne błędy (nawet "używanie przestrzeni nazw std' :) – slashmais
@lashmais, oczywiście to prawda. Ale w tak małych fragmentach myślę, że jest to dozwolone. Najważniejsze, żeby się do tego nie przyzwyczaić - jeśli to zrobisz, zapomnisz nie pisać tak w prawdziwym kodzie. I tak - naprawione! –
Gdy kompilator próbuje rozwiązać f
w f(x)
stwierdzi B::f
ponieważ jesteśmy w przestrzeni nazw B
. Znajduje także A::f
przy użyciu argument dependent lookup od x
jest instancją X
, która jest zdefiniowana w przestrzeni nazw A
. Stąd niejednoznaczność.
Deklaracja z użyciem B::f
nie ma żadnych efektów, ponieważ jesteśmy już w przestrzeni nazw B
. Aby uzyskać dwuznaczność, użyj A::f(x)
lub B::f(x)
.
- 1. Jak podzielić F [A \/B] do (F [A], M [B])
- 2. Znaczenie podkreślenia w podnośniku [A, B] (f: A => B): Opcja [A] => Opcja [B] = _ mapa f
- 3. Rodzaj minBy [B] (f: ((A, B)) ⇒ B) (ukryte CMP: Kolejność [B]): (A, B)
- 4. Rodzaje wyższych typów - dlaczego możliwe Scala, ale nie F #?
- 5. f: setPropertyActionListener nie powoływać
- 6. Django F nie działa?
- 7. Czy to możliwe (Alternatywne f, Składane f) => Monad f?
- 8. Dlaczego for/f nie ignoruje pustych linii?
- 9. Dlaczego F # nie obsługuje klas zagnieżdżonych?
- 10. Dlaczego <f: validateBean /> nie działa?
- 11. F # Funkcje a wartości
- 12. Dlaczego nie można sparametryzować nie-częściowych aktywnych wzorców w F #?
- 13. Różnica między `let f = fun a -> a-1` i` let f a = a-1` w F #
- 14. Dlaczego nie można tego zrozumieć za pomocą interferencji typu F #?
- 15. Udowodnienie F (f BOOL) = bool
- 16. dlaczego leży debugger F #?
- 17. F # pętli w F #
- 18. Wspólny wzór udziałem składu funkcji (\ A B -> f (G) (g b))
- 19. Nie można zwrócić JSON-a z Suave F #
- 20. .htaccess! -f reguła nie działa
- 21. Dlaczego (a | b) jest równoważne z - (a & b) + b?
- 22. F # Dodanie
- 23. Dlaczego nie ma dwuznaczności w tym wzorze diamentu?
- 24. Dlaczego kompilator F # nie działa z tym operatorem?
- 25. Czy zawsze mam `(a/b * b) + a% b == a`, gdy b nie jest zerem?
- 26. Dlaczego nie mogę utworzyć F-ograniczony obiekt w Scala
- 27. klasa A ma jeden parametr, ale typ B ma jeden:
- 28. Dlaczego ng-show nie działa po wpisaniu F lub N
- 29. Dlaczego występuje różnica wydajności między LINQ (C#) a Seq (f #)
- 30. Dlaczego funkcja F # nie zapewnia niestandardowego przeciążenia dla operatora ==?
Można zablokować ADL na stronie wywołania, nawiasyzując nazwę funkcji. Użycie '(f) (x)' rozwiązuje niejednoznaczność. –
Oczywiście "używanie B :: f;' nie jest potrzebne w żadnym z powyższych fragmentów kodu – Tony