[英]How to use std::bind for adding member callback to a messenger system
I am currently trying to implement a messenger system for my game engine. 我目前正在尝试为我的游戏引擎实现Messenger系统。 It uses function callbacks of the form:
它使用以下形式的函数回调:
typedef std::function<void(const Message &)> Callback;
I want all objects to be able to subscribe to a message of a specific type (where the type is just a string). 我希望所有对象都能够订阅特定类型的消息(该类型只是一个字符串)。 Subscribing means adding their "onEvent" function to the dictionary of callbacks.
订阅意味着将其“ onEvent”功能添加到回调字典中。
mutable std::map<std::string, std::vector<Callback>> callbackDictionary;
The update function then calls these functions and passes the according message (from which the "onEvent" functions can get their data) 然后,更新函数将调用这些函数并传递相应的消息(“ 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);
}
}
Now, my problem is that I am not quite sure how to bind these "onEvent" functions. 现在,我的问题是我不太确定如何绑定这些“ onEvent”功能。 I have just recently switched to C++11 and the concept of function objects and
std::bind
is quite new to me. 我最近刚切换到C ++ 11,函数对象和
std::bind
的概念对我来说还是很新的。 So here is what I have tried: 所以这是我尝试过的:
messageBus.Subscribe("Message/Click",std::bind(&ClickableComponent::OnClick, this));
where the ClickableComponent::OnClick
function has the required signature: 其中
ClickableComponent::OnClick
函数具有必需的签名:
void OnClick(const Message &);
and the Subscribe function just adds the passed function to the dictionary 而Subscribe函数只是将传递的函数添加到字典中
void Messenger::Subscribe(std::string type, Callback callbackFunction) const
{
callbackDictionary[type].push_back(callbackFunction);
}
(The push_back is used because there is a vector of callbacks for each type) (使用push_back是因为每种类型都有一个回调向量)
The code seems fine to me but the line: 该代码对我来说似乎很好,但代码行:
messageBus.Subscribe("Message/Click", std::bind(&ClickableComponent::OnClick, this));
Gives me the error: picture of the error discription 给我错误:错误说明的图片
I have tried all kinds of stuff like forwarding the Messenger reference and using placeholders, but I have the feeling that I am doing something else wrong. 我尝试了各种方法,例如转发Messenger参考和使用占位符,但是我感觉自己在做其他错误。 Also, better idea on how to implement this messenger system are appreciated ^^
此外,赞赏有关如何实现此Messenger系统的更好的主意^^
Thanks for your help! 谢谢你的帮助!
std::bind
is not necessary in your case, lambda function would do just fine: std::bind
在您的情况下不是必需的,lambda函数就可以了:
messageBus.Subscribe("Message/Click", [this](const Message& msg) { OnClick(msg); });
std::bind
is more useful in specific cases of metaprogramming. std::bind
在元编程的特定情况下更有用。
But if you're curios enough to see how to use std::bind
: 但是,如果您有足够的好奇心,可以看看如何使用
std::bind
:
messageBus.Subscribe("Message/Click",
std::bind(&ClickableComponent::OnClick, this, std::placeholders::_1));
Here, as you see, you missed std::placeholders::_1
. 如您所见,在这里您错过了
std::placeholders::_1
。 Your functor signature is void(const Message&)
, but you try to store a member function which signature can be regarded as void(ClickableComponent*, const Message&)
. 您的函子签名是
void(const Message&)
,但是您尝试存储一个成员函数,该签名可以被视为void(ClickableComponent*, const Message&)
。 To partially apply some arguments (what std::bind
does) you need to specify arguments that you'd like to bind and arguments that you leave unbound. 要部分应用某些参数(
std::bind
作用),您需要指定要绑定的参数和未绑定的参数。
Lambda is preferred because usually it's shorted, more flexible and more readable. Lambda是首选,因为通常它更短,更灵活且更具可读性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.