如何使用std :: bind将成员回调添加到messenger系统

时间:2017-11-05 11:56:20

标签: c++ c++11 stdbind

我目前正在尝试为我的游戏引擎实现一个信使系统。它使用以下形式的函数回调:

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

我希望所有对象都能够订阅特定类型的消息(类型只是一个字符串)。订阅意味着添加他们的&#34; onEvent&#34;功能到回调字典。

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

更新函数然后调用这些函数并传递相应的消息(&#34; onEvent&#34;函数可以从中获取数据)

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

现在,我的问题是我不太确定如何绑定这些&#34; onEvent&#34;功能。我刚刚转到C ++ 11,函数对象和std::bind的概念对我来说是一个新手。所以这就是我的尝试:

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

ClickableComponent::OnClick函数具有所需签名:

void OnClick(const Message &);

并且Subscribe函数只是将传递的函数添加到字典

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

给我错误: picture of the error discription

我尝试了各种各样的东西,例如转发Messenger引用和使用占位符,但我觉得我做错了什么。此外,有关如何实施此信使系统的更好的想法,我们赞赏^^

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

在您的情况下,

messageBus.Subscribe("Message/Click", [this](const Message& msg) { OnClick(msg); }); 不是必需的,lambda函数可以正常运行:

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。要部分应用一些参数(package main import ( f "fmt" "os" s "strings" ) const bufsize = 1024 * 64 func main() { atom := "y\n" if len(os.Args) > 1 { atom = s.Join(os.Args[1:], " ") + "\n" } buf := s.Repeat(atom, bufsize / len(atom)) for { f.Print(buf) } } 做什么),您需要指定要绑定的参数和未绑定的参数。

Lambda是首选,因为它通常缩短,更灵活,更易读。