【问题标题】:Vector of Vector of (member) function pointers(成员)函数指针的向量的向量
【发布时间】:2013-03-02 18:47:51
【问题描述】:

我正在为我当前的实验项目构建一个简单的侦听器/回调机制。而且我坚持实现一个容器结构,它似乎应该是指针向量的向量。我选择这种方式是因为我希望根向量简单地具有事件类型的 KEY 假设是一个枚举(int),然后在这个键上我想存储指向该事件类型可用方法的指针向量。在逻辑表示中类似于:

[EVENT_TYPE_QUIT]
                 [ptr1]
                 [ptr2]
                 [ptr3]
                 [ptr4]
                 [....]
[EVENT_TYPE_HELLO]
                 [....]
                 [....]

typedef enum {
   EVENT_TYPE_QUIT,
   EVENT_TYPE_HELLO,
   ...
} EventType;

所以简化的实现看起来像这样(它实际上是一个模板,但想象一下 T 是您可以映射事件的任何用户类型)。

class EventMapper {
    ...

    typedef void (T::*functionPtr)(); // simple pointer to T member function with no args.

    std::vector< std::vector<functionPtr> > eventCallbacks;

    void mapEvent(const EventType type, functionPtr callback) {

        // here i need to map type to callback
        // each type can have multiple callbacks
        // T can have only distinct event types as "key"

        // this i tried but doesn't work

        eventCallbacks[type].push_back(callback);

    }

    ...
}

预期的实现类似于:

EventMapper<SupaDupaClass> mapper;
mapper.mapEvent(EVENT_TYPE_HELLO, &SupaDupaClass::didYouSayHello);

等等……

我真的想使用矢量而不是地图来更轻松地分配唯一键吗? 谢谢

【问题讨论】:

    标签: c++


    【解决方案1】:

    如果我正确阅读了您的代码,那么您正在访问一个未初始化的条目。

    您应该首先使用空向量初始化 eventCallbacks,例如

    eventCallbacks.assign(10,std::vector())

    【讨论】:

      【解决方案2】:

      您可以使用std::map 将 event_type 映射到回调向量。并考虑使用std::function 代替函数指针以获得灵活性。

      一种可能的实现方式是:

      #include <vector>
      #include <map>
      #include <functional>
      #include <iostream>
      
      enum class event_type
      {
          event_one,
          event_two
      };
      
      void func1() { std::cout << "func1" << std::endl; }
      class my_listener { public: void func() { std::cout << "my_listener::func" << std::endl; } };
      
      int main()
      {
          std::map<event_type, std::vector<std::function<void ()>>> m;
      
          my_listener lst;
          m[event_type::event_one].push_back(std::bind(&my_listener::func, lst));
          m[event_type::event_one].push_back(&func1);
      
          // invoke callbacks (may be used in the code that raises events)
          for(auto& kv : m)
          {
              for(auto& f : kv.second) {
                  f();
              }
          }
      
          return 0;
      }
      

      编辑: 您可以考虑使用Boost.Signals2 库。

      【讨论】:

        猜你喜欢
        • 2012-12-16
        • 2017-05-16
        • 2013-10-13
        • 1970-01-01
        • 1970-01-01
        • 2011-08-02
        • 1970-01-01
        相关资源
        最近更新 更多