C ++ - правильный способ сопоставления объектов (например, строк) с функциями-членами в таблице - PullRequest
3 голосов
/ 31 октября 2019

Я обрабатываю события, определенные сторонним API. События идентифицируются строковыми идентификаторами, т.е. "EventABC"

Мне нужно сопоставить эти (строковые) события в таблице с функциями-членами объекта.

ВОПРОС

Какой самый безопасный и чистый способ сделать это?

Ответы [ 2 ]

7 голосов
/ 31 октября 2019

Без дополнительных ограничений это легко сделать с помощью std::map или std::unordered_map от std::string до std::function<void()>. В C ++ 11 вы можете использовать лямбда-выражения для ненавязчивого захвата объекта 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 отсутствует на карте (в настоящее время он выдает исключение при попытке вызвать функцию, созданную по умолчанию).

1 голос
/ 31 октября 2019

Можно сделать что-то вроде ниже, обернуть методы в 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]();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...