2013-03-02 3 views
0

현재 사용중인 프로젝트의 간단한 수신기/콜백 메커니즘을 구성 중입니다. 그리고 컨테이너 구조를 구현하는 데 방해가됩니다. 포인터의 벡터 벡터가되어야합니다. 루트 벡터에 단순한 이벤트 유형의 KEY가 있기를 원하기 때문에이 방법을 선택합니다. enum (int)을 말한 다음이 키에서이 이벤트 유형에 사용할 수있는 메서드에 대한 포인터 벡터를 저장하려고합니다. 같은 논리적 표현 무언가 :(member) 함수 포인터의 벡터 벡터

[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); 

등 ...

정말 쉽게 고유 키 할당을 위해 벡터 대신지도를 사용 하시겠습니까? 감사합니다.

답변

1

코드를 올바르게 읽으면 초기화되지 않은 항목에 액세스하고 있습니다.

1

당신은의 벡터에 EVENT_TYPE를 매핑 할 std::map을 사용할 수 있습니다

먼저,

eventCallbacks.assign 같은 빈 벡터와 eventCallbacks를 초기화한다 (() (10), 표준 : : 벡터) 콜백. 유연성을 위해 함수 포인터 대신 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 라이브러리를 사용하는 것이 좋습니다.