2013-06-15 12 views
5

W poniższym kodzie nie mogę zrozumieć, dlaczego wywołanie "zastosuj" jest zgłaszane jako niejednoznaczne. Istnieje tylko jedno dopuszczalne dopasowanie dla podanego parametru (A_applicator::apply). Uwaga: Chciałbym bardzo docenić odniesienia do normy, które pomogłyby mi określić przepływ rozdzielczości, który powoduje tę niejednoznaczność.Dlaczego to połączenie wirtualne jest niejednoznaczne?

struct A { }; 
struct B { }; 
struct A_D : public A { }; 

struct A_applicator { 
    virtual void apply(A) { } 
}; 
struct B_applicator { 
    virtual void apply(B) { } 
}; 
struct dual_applicator : public B_applicator, public A_applicator { 
}; 

int main() { 
    dual_applicator app; 
    A_D d; 
    app.apply(d); 
} 

(Online Demo)

+6

Masz klasę, która pochodzi z dwóch klas bazowych, które nie zastępują 'apply()'. Połączenie wirtualne, które próbuje przeszukać drzewo dziedziczenia i spełnia dwie lub więcej opcji, jest nieprawidłowe. Masz swoją niejednoznaczność. – CodaFi

+0

Rzeczywiście, zapomniałem o klauzulach "używania". Dziękuję Ci. –

Odpowiedz

6

Wydaje się, że uważasz, że nie powinna to być dwuznaczność, ponieważ jedna z funkcji nie może być wywołana, w oparciu o typ argumentów. Ale to nie działa jak rozpoznawanie nazw w C++.

Tak to działa, mniej więcej: nazwa funkcji zostaje rozwiązana w zestaw przeciążeniowy. A następnie lista argumentów służy do wyboru między funkcjami w tym zestawie.

Twój problem polega na tym, że pierwszego kroku nie można wykonać, ponieważ nazwa apply, w jaki sposób jest używana, może odnosić się do dwóch różnych zestawów przeciążeniowych, a kompilator nie wie, którego użyć. Nie zaczął nawet patrzeć na parametry!

Rozwiązania są proste:

A) powiedzieć, które funkcjonują chcesz:

app.A_applicator::apply(d); 

b) stosowanie using zbudować jednolity zestaw przeciążeniem funkcji członkowskich, tak oczekiwana rozdzielczości używając argumentów służy .

struct dual_applicator : public B_applicator, public A_applicator { 
    using A_applicator::apply; 
    using B_applicator::apply; 
}; 
+0

To ładne jasne wyjaśnienie. –

0

Klasa dual_applicator nie zastępują wirtualnego funkcji apply.

Powiązane problemy