Bob
Bob

Reputation: 4970

C++ - proper way to map objects (like strings) to member functions in table

I'm processing events defined by a 3rd party API. The events are identified by string identifiers i.e. "EventABC"

I need to map these (string) events in a table to member-functions of an object.

QUESTION

What's the safest and cleanest way to do this?

Upvotes: 3

Views: 792

Answers (2)

Max Langhof
Max Langhof

Reputation: 23691

Without further constraints, this is easily accomplished with a std::map or std::unordered_map from std::string to std::function<void()>. With C++11 you can use lambdas to unobtrusively capture the this object to call the member functions on.

class HandlerHandler
{
    std::map<std::string, std::function<void()>> handlers;

    void foo();
    void bar();
    void frobnicate();

    HandlerHandler()
    {
        handlers["FOO"] = [this](){ foo(); };
        handlers["BAR"] = [this](){ bar(); };
        handlers["FROB"] = [this](){ frobnicate(); };
    }

    void handle(std::string h)
    {
        handlers[h]();
    }
};

https://godbolt.org/z/nbygdF

You may want to guard against the case of h not being present in the map (currently it will throw an exception as it tries to call a default-constructed function).

Upvotes: 7

Darren Smith
Darren Smith

Reputation: 2488

Can do something like below, wrap the methods in std::function

#include <iostream>
#include <string>
#include <functional>
#include <map>

struct Target
{
    void member1() {
        std::cout << "member1\n";
    }

    void member2() {
        std::cout << "member2\n";
    }
};


int main()
{   
   // events will be called on this object
   Target myTarget; 

   std::map<std::string, std::function<void(void)>> table;
   table.insert({"member1", std::bind(&Target::member1, &myTarget)});
   table.insert({"member2", std::bind(&Target::member2, &myTarget)});

   std::string event = "member2";
   table[event]();
}

Upvotes: 1

Related Questions