Question

I need to have the ability to have a Base class that can store pointers to member functions not only for its own methods but also for subclasses. Here is an example of what I want USING LAMBDAS, but I would like to be able to do it with MEMBER FUNCTIONS:

struct Base
{
    void registerFunc(std::string const& name, std::function<void *(void *)> code)
    { 
        functionTable_[name] = code; 
    }

    void *invokeFunc(std::string const& name, void *arg)
    {
        auto x = functionTable_[name];
        auto func = std::bind(x, _1);
        return func(arg);
    }

    Base()
    {
        registerFunc("hello", [this](void *arg) { printf("hello"); return nullptr; });
        invokeFunc("hello");
    }
private:
    std::unordered_map<std::string, std::function<void *(void *)>> functionTable_;
};  

struct Derived : Base
{
    Derived()
    {
        registerFunc("world", [this] (void *arg) { printf("world"); return nullptr; });
        invokeFunc("world");
    }

    // Instead of lambdas, I would like to be able to put member
    // functions like this into the std::unordered_map of the Base class
    void *memberFunc(void *arg) { printf("oyoyoy"; }
};  
Was it helpful?

Solution

First of all your invokeFunc method does not need to use std::bind() and should at least check if function is there:

void *invokeFunc(std::string const& name, void *arg)
{
    auto &x = functionTable_[name];
    if( !x ) return 0;
    return x(arg);
}

But better would be to use std::map::find() I believe

Second you can use std::bind() to pass method:

Derived()
{
    registerFunc("world", [this] (void *arg) { printf("world"); return nullptr; });
    invokeFunc("world");
    registerFunc("method", std::bind( &Derived::memberFunc, this, _1 ) ) );
    invokeFunc("method");
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top