    #include <typeinfo>
    #include <typeindex>
    #include <unordered_map>

    struct Command { virtual ~Command() {}; };

    struct SpecificCommandA: Command {};
    struct SpecificCommandB: Command {};
    struct SpecificCommandC: Command {};


    struct Base {
        virtual ~Base() {}; 

        virtual void modify_command(Command &c, std::type_index); // default

        void modify_command(Command &c) {
            modify_command(c, std::type_index(typeid(c)));
        }
    };

    template<typename Der, typename SpecC> struct Modifier {
        static void execute(Der &d, Command &c) {
            d.modify_command(static_cast<SpecC &>(c)); 
        }
    };

    struct Derived: Base {
        using Base::modify_command;
        virtual void modify_command(SpecificCommandB &); // overload & override

        void modify_command(Command &c, std::type_index ti) override {
            using callable = void (*)(Derived &, Command &);
            const static std::unordered_map<std::type_index, callable> derived_map =
            {
                { std::type_index(typeid(SpecificCommandB)), Modifier<Derived, SpecificCommandB>::execute }
            };
            auto find_result = derived_map.find(ti);
            if(derived_map.end() == find_result) { Base::modify_command(c, ti); }
            else { (*find_result->second)(*this, c); }
        }
    };

    struct DerivedOfDerived: Derived {
        using Derived::modify_command;
        virtual void modify_command(SpecificCommandB &); // overload & override
        virtual void modify_command(SpecificCommandC &);

        void modify_command(Command &c, std::type_index ti) override {
            using callable = void (*)(DerivedOfDerived &, Command &);
            const static std::unordered_map<std::type_index, callable> derived_map =
            {
                { std::type_index(typeid(SpecificCommandB)), Modifier<DerivedOfDerived, SpecificCommandB>::execute },
                { std::type_index(typeid(SpecificCommandC)), Modifier<DerivedOfDerived, SpecificCommandC>::execute }
            };
            auto find_result = derived_map.find(ti);
            if(derived_map.end() == find_result) { Derived::modify_command(c, ti); }
            else { (*find_result->second)(*this, c); }
        }
    };

    #include <iostream>

    void Base::modify_command(Command &, std::type_index) { std::cout << "Default" << std::endl; }
    
    void Derived::modify_command(SpecificCommandB &) { std::cout << "B in Derived" << std::endl; }
    void DerivedOfDerived::modify_command(SpecificCommandB &) { std::cout << "B in DerivedOfDerived" << std::endl; }
    void DerivedOfDerived::modify_command(SpecificCommandC &) { std::cout << "C" << std::endl; }



    int main(int argc, const char *argv[]) {
        SpecificCommandA a;
        SpecificCommandB b;
        Derived d;
        d.modify_command(a);
        d.modify_command(static_cast<Command &>(b));
        d.modify_command(b);
        DerivedOfDerived dod;
        SpecificCommandC c;
        dod.modify_command(a);
        dod.modify_command(b);
        dod.modify_command(c);
        return 0;
    }