“事件”和成员函数指针的C++映射

“事件”和成员函数指针的C++映射,c++,templates,callback,function-pointers,member-function-pointers,C++,Templates,Callback,Function Pointers,Member Function Pointers,我已经设法编写了一个模板类来像回调一样工作,这是从这个问题的公认答案中学到的 我希望有一个字符串键和回调值的映射,以便调用与字符串匹配的正确回调。这很好,但我需要映射来支持来自不同类的回调。现在它只能与一个类一起工作。由于模板的原因,它可以是任何类,但只能是来自同一类的回调集合 class Apple { public: void Red () { cout << "aa"; } }; class Orange { public: void

我已经设法编写了一个模板类来像回调一样工作,这是从这个问题的公认答案中学到的

我希望有一个字符串键和回调值的映射,以便调用与字符串匹配的正确回调。这很好,但我需要映射来支持来自不同类的回调。现在它只能与一个类一起工作。由于模板的原因,它可以是任何类,但只能是来自同一类的回调集合

class Apple {
public:
    void Red () {
        cout << "aa";
    }
};

class Orange {
public:
    void Blue () {
        cout << "bb";
    }
};

template <typename T>
class Callback {
    T *obj;
    void (T::*ptr) (void);

public:
    Callback (T *obj, void (T::*ptr) (void)) : obj (obj), ptr (ptr) {

    }

    void Call () {
        (obj->*ptr) ();
    }
};
因此,如果这一点起作用,我将能够把谈话和走路都放在地图上


这到底是可能的还是我的观点一开始就有缺陷?

疯狂在于:不要将回调绑定到特定的类。相反,使用std::function对象并创建合适的函数对象:当需要对不同的类进行操作时,还需要对不同类型的对象进行操作。使用std::函数应该做到这一点,例如:

std::map<std::string, std::function<void()>> operations;
operations["talk"] = std::bind(&ChildA::Talk, ChildA());
operations["walk"] = std::bind(&ChildB::Walk, ChildB());
operations["talk"]();

这里不需要继承。只需使用std::function存储成员函数指针,并使用std::bind将成员函数指针和对象实例绑定在一起

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

struct Apple {
    void Red () {
        std::cout << "aa\n";
    }
};

struct Orange {
    void Blue () {
        std::cout << "bb\n";
    }
};

int main()
{
    std::map<std::string, std::function<void()>> m;
    Apple a;
    Orange o;

    m["apple"] = std::bind(&Apple::Red, a);
    m["orange"] = std::bind(&Orange::Blue, o);

    m["apple"]();
    m["orange"]();
}
class Base { };

class ChildA : public Base {
public:
    void Talk ();
}

class ChildB : public Base {
public:
    void Walk ();
}
std::map<std::string, std::function<void()>> operations;
operations["talk"] = std::bind(&ChildA::Talk, ChildA());
operations["walk"] = std::bind(&ChildB::Walk, ChildB());
operations["talk"]();
#include <functional>
#include <map>
#include <string>
#include <iostream>

struct Apple {
    void Red () {
        std::cout << "aa\n";
    }
};

struct Orange {
    void Blue () {
        std::cout << "bb\n";
    }
};

int main()
{
    std::map<std::string, std::function<void()>> m;
    Apple a;
    Orange o;

    m["apple"] = std::bind(&Apple::Red, a);
    m["orange"] = std::bind(&Orange::Blue, o);

    m["apple"]();
    m["orange"]();
}
aa
bb