#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);
}