2013-06-15 10 views
5

Im unten stehenden Code kann ich nicht herausfinden, warum der Aufruf von "apply" als mehrdeutig gemeldet wird. Es gibt nur eine akzeptable Übereinstimmung für den angegebenen Parameter (A_applicator::apply). Hinweis: Ich würde sehr gerne Verweise auf den Standard schätzen, die mir helfen würden, den Auflösungsfluss zu bestimmen, der diese Mehrdeutigkeit verursacht.Warum ist dieser virtuelle Anruf mehrdeutig?

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

Sie haben eine Klasse, die von zwei Basisklassen abgeleitet ist, die 'apply()' nicht überschreibt. Ein virtueller Aufruf, der versucht, den Vererbungsbaum zu durchsuchen und zwei oder mehr realisierbare Optionen zu erfüllen, ist ungültig. Da ist deine Zweideutigkeit. – CodaFi

+0

Tatsächlich habe ich meine 'using' Klauseln vergessen. Vielen Dank. –

Antwort

6

Sie scheinen zu denken, dass es keine Mehrdeutigkeit sein sollte, weil eine der Funktionen nicht aufgerufen werden kann, basierend auf dem Typ der Argumente. Aber so funktioniert die Namensauflösung von C++ nicht.

So funktioniert es mehr oder weniger: Der Name der Funktion wird in eine Überladungsgruppe aufgelöst. Und dann wird die Argumentliste verwendet, um zwischen den Funktionen in diesem Satz zu wählen.

Ihr Problem ist, dass der erste Schritt nicht getan werden kann, weil der Name apply, wie es verwendet wird, auf zwei verschiedene Überladungssätze verweisen kann, und der Compiler weiß nicht, welchen zu verwenden. Es hat nicht einmal begonnen, die Parameter zu betrachten!

Die Lösungen sind einfach:

A) Sagen Sie, welche Funktion Sie wollen:

app.A_applicator::apply(d); 

B) using Verwenden Sie eine einheitliche Überlastung Satz von Elementfunktionen zu bauen, so dass die erwartete Auflösung Argumenten verwendet wird .

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

Das ist eine schöne, klare Erklärung. –

0

Klasse dual_applicator enthebt nicht virtuelle Funktion apply.

Verwandte Themen