C++ - 将对象(如字符串)映射到 table 中的成员函数的正确方法

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

我正在处理由第 3 方定义的事件 API。 事件由字符串标识符标识,即 "EventABC"

我需要将 table 中的这些(字符串)事件映射到对象的成员函数。

问题

执行此操作最安全、最干净的方法是什么?

可以做类似下面的事情,将方法包装在 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]();
}

在没有进一步限制的情况下,使用从 std::stringstd::function<void()>std::mapstd::unordered_map 可以轻松实现。使用 C++11,您可以使用 lambdas 以不显眼的方式捕获 this 对象以调用其成员函数。

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

您可能希望防止映射中不存在 h 的情况(目前它会在尝试调用默认构造的函数时抛出异常)。