2013-06-15 8 views
5

Nel seguente codice non riesco a capire perché la chiamata a "applicare" sia segnalata come ambigua. Esiste una sola corrispondenza accettabile per il parametro fornito (A_applicator::apply). Nota Apprezzerei molto i riferimenti allo standard che mi aiuterebbero a determinare il flusso di risoluzione che causa questa ambiguità.Perché questa chiamata virtuale è ambigua?

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

Si dispone di una classe derivata da due classi base che non esegue l'override di 'apply()'. Una chiamata virtuale che tenta di cercare l'albero di ereditarietà e soddisfa due o più opzioni valide non è valida. C'è la tua ambiguità. – CodaFi

+0

Infatti, ho dimenticato le mie clausole 'using'. Grazie. –

risposta

6

Sembra che tu non debba essere ambiguo perché una delle funzioni non può essere chiamata, in base al tipo di argomenti. Ma non è così che funziona la risoluzione dei nomi in C++.

Ecco come funziona, più o meno: il nome della funzione è stato risolto in un set di sovraccarico. E poi la lista degli argomenti è usata per scegliere tra le funzioni di quel set.

Il tuo problema è che il primo passo non può essere fatto, perché il nome apply come è usato, può riferirsi a due diversi set di sovraccarico, e il compilatore non sa quale usare. Non ha nemmeno iniziato a guardare i parametri!

Le soluzioni sono facili:

A) Dire che funzione che si desidera:

app.A_applicator::apply(d); 

B) Utilizzare using per costruire una serie di sovraccarico unificato di funzioni membro, quindi viene utilizzato la risoluzione prevista usando argomenti .

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

Questa è una bella spiegazione chiara. –

0

Classe dual_applicator non sovrascrive funzione virtuale apply.

Problemi correlati