Chcę wykonać przeciążone funkcje, które pobierają wspólny wskaźnik do klasy bazowej i klas pochodnych. Wydaje się działać dla referencji i surowych wskaźników, ale nie dla współdzielonych wskaźników w przypadku dodatkowej klasy pochodnej. Zobacz przykładowy kod:Funkcja przeciążania z niejednoznacznością argumentu współdzielonego wskaźnika
#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);
}
uzyskać: „error C2668:«IsBase»: niejednoznaczne wywołanie funkcji przeciążonej” przy użyciu programu Visual Studio 2012, ale również uzyskać ten sam wynik, gdy próbuję kod tutaj http://ideone.com/6uoa0p .
To nie wydaje się pożądane zachowanie (jak to działa na rzeczy "surowe"). Czy to jest ograniczenie szablonów, czy istnieje inny powód, dlaczego to nie działa lub jest to błąd? I jak mogę sprawić, żeby działało w najmniej brzydki sposób?
Najlepszym mogę wymyślić jest
//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());
}
Dlaczego chcesz tego? Wystarczy tylko podać funkcję podstawową, z radością zaakceptuje pochodną wskaźnik klasy. Jeśli chcesz uchwycić pochodne obiekty klas, twoja metoda i tak nie zadziała, ponieważ wymagałoby to przeprowadzenia wysyłki na typ dynamiczny argumentu funkcji. Jeśli programista niejawnie przekształca 'Ptr' na 'Ptr ' przed przejściem, to podejście przeładowania zepsuje się. –
@ JohannesSchaub-litb Nie myślałem o tej sytuacji. Być może będę musiał przemyśleć to, co chcę. – Barabas