2017-11-05 9 views
0

현재 내 게임 엔진 용 메신저 시스템을 구현하려고합니다. 이 형태의 함수 콜백을 사용메신저 시스템에 멤버 콜백을 추가하기 위해 std :: bind를 사용하는 방법

typedef std::function<void(const Message &)> Callback; 

나는 모든 개체 (유형 그냥 문자열) 특정 유형의 메시지를 구독 할 수 있어야합니다. 구독은 콜백 사전에 "onEvent"함수를 추가하는 것을 의미합니다.

mutable std::map<std::string, std::vector<Callback>> callbackDictionary; 

이 업데이트 기능은 다음이 함수를 호출하고 (이하 "의 onEvent"기능은 데이터를 얻을 수있는)에 따라 메시지 이제

for each (auto message in messageList) 
{ 
    // find the list of respective callbacks 
    auto it = callbackDictionary.find(message->GetType()); 

    // If there are callbacks registered for this message type 
    if (it != callbackDictionary.end()) 
    { 
     // call every registred callback with the appropreate message 
     for each (auto callback in it->second) 
      callback(*message); 
    } 
} 

를 전달, 내 문제는 내가 아주 확실하지 않다이다 이러한 "onEvent"함수를 바인딩하는 방법. 나는 최근에 C++ 11로 바뀌었고 함수 객체의 개념을 가지고 있으며 std::bind은 나에게 아주 새로운 것이다. ClickableComponent::OnClick 기능이 요구되는 서명이

messageBus.Subscribe("Message/Click",std::bind(&ClickableComponent::OnClick, this)); 

:

void OnClick(const Message &); 

와 구독 기능은 단지 사전

void Messenger::Subscribe(std::string type, Callback callbackFunction) const 
{ 
    callbackDictionary[type].push_back(callbackFunction); 
} 

에 전달 된 기능을 추가 그래서 여기 내가 시도한 것입니다 (각 유형에 대한 콜백 벡터가 있기 때문에 push_back이 사용됩니다)

messageBus.Subscribe("Message/Click", std::bind(&ClickableComponent::OnClick, this)); 

나에게 오류 제공합니다 : 414,코드 나하지만 라인에 잘 보인다 내가 메신저 참조를 전달하고 자리 표시자를 사용하여 같은 물건의 모든 종류의 시도 picture of the error discription

을,하지만 난 느낌이 내가 다른 뭔가 잘못하고있다. 또한,이 메신저 시스템을 구현하는 방법에 대한 더 좋은 아이디어는 높이 평가됩니다. ^^

당신의 도움에 감사드립니다!

+6

'std :: bind' 대신에 람다 함수를 사용하십시오. – user0042

+0

'for each..in'을 사용하지 마십시오. 비표준 확장이며 더 이상 유용하지 않습니다. 'for (auto x : xs) {}'를 사용하십시오. –

답변

3

std::bind 귀하의 경우에는 필요하지 않습니다, 람다 함수는 잘 할 것이다 :

messageBus.Subscribe("Message/Click", [this](const Message& msg) { OnClick(msg); }); 

std::bind는 메타 프로그래밍의 특정 경우에 더욱 유용하다.

는하지만 골동품이라면 충분히 std::bind을 사용하는 방법을 볼 수 : 당신이 볼로

다음
messageBus.Subscribe("Message/Click", 
    std::bind(&ClickableComponent::OnClick, this, std::placeholders::_1)); 

는, 당신은 std::placeholders::_1를 놓쳤다. 펑터 시그니처가 void(const Message&)이지만 서명을 void(ClickableComponent*, const Message&)으로 간주 할 수있는 멤버 함수를 저장하려고합니다. 일부 인수를 부분적으로 적용하려면 (std::bind의 경우) 바인딩하려는 인수와 바인딩을 해제 한 인수를 지정해야합니다.

람다는 일반적으로 쇼트되고 유연하며 읽기 쉽기 때문에 선호됩니다.