C++ boost::bind 和 boost::function、类成员函数回调和运算符==。我做错了什么?
我在使用 boost::bind 和 boost::function 并将 boost::function 作为回调传递到另一个类中时遇到问题。
这是一个有问题的情况的例子:
typedef boost::function<void (bool)> callbackFunction;
class HasCallback
{
public:
HasCallback() : value(0)
{
}
int value;
void CallBackFunction(bool changed)
{
std::cout << "HasCallback class. CallBackFunction called. Parameter: " << value << std::endl;
}
};
class ReceivesCallback
{
public:
void AddCallback(callbackFunction newFunc)
{
callbacks.push_back(newFunc);
}
void execute(int &i)
{
for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
{
(*it)(i++);
}
}
void RemoveHandler(callbackFunction oldFunc)
{
for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
{
if((*it) == oldFunc)
{
callbacks.erase(it);
break;
}
}
}
private:
std::vector<callbackFunction> callbacks;
};
int main()
{
HasCallback hc;
ReceivesCallback rc;
rc.AddCallback(boost::bind(&HasCallback::CallBackFunction, &hc, _1));
hc.value = 123;
HasCallback hc2;
rc.AddCallback(boost::bind(&HasCallback::CallBackFunction, &hc2, _1));
hc2.value = 321;
int a = 0;
rc.RemoveHandler(boost::bind(&HasCallback::CallBackFunction, &hc2, _1));
rc.execute(a);
}
我遇到的问题是这甚至无法编译。它在 if((*it) == oldFunc) 行的 ReceivesCallback::RemoveHandler 中失败,并出现错误,指出对于我正在尝试执行的操作,有多个运算符 == 重载。 我一直在寻找这个,但找不到我做错了什么。另外,我不断发现矛盾的信息,一个说可以比较 boost::function-s ,另一个说不能。我可以在 boost/function_base.hpp 中看到 operator== 函数,我相信这应该可以工作,我只是似乎不知道如何工作。有人可以帮我吗?我怀疑它失败了,因为需要完全指定 boost::bind 的参数(具体值),但这是我在开发的代码中无法得到的东西,我只需要知道传递的处理程序是否是注册与否,因为我绑定到一个对象,所以它应该具有区分所需的所有信息。
I've got a problem with using boost::bind and boost::function and passing boost::function as a callback into another class.
Here's an example that is the problematic situation:
typedef boost::function<void (bool)> callbackFunction;
class HasCallback
{
public:
HasCallback() : value(0)
{
}
int value;
void CallBackFunction(bool changed)
{
std::cout << "HasCallback class. CallBackFunction called. Parameter: " << value << std::endl;
}
};
class ReceivesCallback
{
public:
void AddCallback(callbackFunction newFunc)
{
callbacks.push_back(newFunc);
}
void execute(int &i)
{
for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
{
(*it)(i++);
}
}
void RemoveHandler(callbackFunction oldFunc)
{
for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
{
if((*it) == oldFunc)
{
callbacks.erase(it);
break;
}
}
}
private:
std::vector<callbackFunction> callbacks;
};
int main()
{
HasCallback hc;
ReceivesCallback rc;
rc.AddCallback(boost::bind(&HasCallback::CallBackFunction, &hc, _1));
hc.value = 123;
HasCallback hc2;
rc.AddCallback(boost::bind(&HasCallback::CallBackFunction, &hc2, _1));
hc2.value = 321;
int a = 0;
rc.RemoveHandler(boost::bind(&HasCallback::CallBackFunction, &hc2, _1));
rc.execute(a);
}
The problem I'm having is that this doesn't even compile. It fails within ReceivesCallback::RemoveHandler in the if((*it) == oldFunc) line with the error saying that there's more than one overload of the operator== for the thing i'm trying to do.
I keep searching for this and can't find what I'm doing wrong. Also, I keep finding contradicting information, one saying that it's possible to compare boost::function-s and another saying it's not. I can see the operator== functions within boost/function_base.hpp and i believe this is supposed to work, I just can't seem to figure out how. Can someone help me out here? My suspicion is that it fails because the parameters of the boost::bind need to be specified fully(be concrete values) but this is something i cannot get in the code I'm developing, I just need to know whether the passed handler is registered or not, since I'm binding to an object it should have all the information neeeded to make the distinction.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
请参阅 Boost.Function 常见问题解答以获取解释: 为什么可以我不是将
boost::function
对象与operator==
或operator!=
进行比较吗?。Boost.Functions 仅提供
boost::function
与任意函数对象的比较。我相信制作您的RemoveHandler
成员函数模板可以解决这个问题:在这里,
oldFunc
可以保持其实际类型,而不会被“包装”在boost::函数
。See Boost.Function FAQ for an explanation : Why can't I compare
boost::function
objects withoperator==
oroperator!=
?.Boost.Functions only provides comparison of a
boost::function
with an arbitrary function object. I believe that making yourRemoveHandler
member function template could fix the issue :Here,
oldFunc
gets to keep its actual type without being 'wrapped' in aboost::function
.