Desidero rendere funzioni sovraccariche che accettano un puntatore condiviso a una classe di base e classi derivate. Sembra funzionare per i riferimenti e i puntatori grezzi, ma non per i puntatori condivisi nel caso di una classe derivata extra. Vedere il codice di esempio:Sovraccarico di funzioni con ambiguità dell'argomento del puntatore condiviso
#include <memory>
class Base{};
class Derived : public Base {};
class ExtraDerived : public Derived {};
bool IsBase(Base*){ return true; }
bool IsBase(Derived*){ return false; }
bool IsBase(std::shared_ptr<Base>){ return true; }
bool IsBase(std::shared_ptr<Derived>){ return false; }
int main()
{
auto derived = std::make_shared<Derived>();
auto extra_derived = std::make_shared<ExtraDerived>();
// works
auto raw_result_derived = IsBase(derived.get());
auto raw_result_extra_derived = IsBase(extra_derived.get());
auto shared_result_derived = IsBase(derived);
// doesn't work
auto shared_result_extra_derived = IsBase(extra_derived);
}
ottengo: "Errore C2668: 'IsBase': chiamata ambigua alla funzione" quando si utilizza Visual Studio 2012, ma anche ottenere lo stesso risultato quando provo il codice a qui http://ideone.com/6uoa0p .
Questo non sembra il comportamento desiderato (in quanto funziona per roba "grezza"). Si tratta di una limitazione del modello, c'è un altro motivo per cui questo non funziona o è un bug? E come posso farlo funzionare nel modo meno brutto?
Il meglio che posso venire in mente è
//ugly workaround
bool IsBase(std::shared_ptr<Base>, Base*){ return true; }
bool IsBase(std::shared_ptr<Derived>, Derived*){ return false; }
template<typename T> bool IsBase(std::shared_ptr<T> input)
{
return IsBase(input, input.get());
}
Perché vuoi questo? Fornisci solo la funzione di base, accetterà felicemente il puntatore della classe derivata. Se vuoi catturare oggetti di classe derivati, il tuo metodo non funzionerà comunque perché avrebbe bisogno di inviare il tipo dinamico dell'argomento della funzione per farlo correttamente. Se il programmatore converte implicitamente il 'Ptr' in un 'Ptr ' prima di passare, questo approccio di sovraccarico si rompe. –
@ JohannesSchaub-litb Non ho pensato a quella situazione. Potrei dover ripensare quello che voglio. – Barabas