C++ boost::bind 和 boost::function、类成员函数回调和运算符==。我做错了什么?

发布于 2024-10-06 07:00:27 字数 1759 浏览 2 评论 0原文

我在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

§普罗旺斯的薰衣草 2024-10-13 07:00:27

请参阅 Boost.Function 常见问题解答以获取解释: 为什么可以我不是将 boost::function 对象与 operator==operator!= 进行比较吗?

Boost.Functions 仅提供 boost::function 与任意函数对象的比较。我相信制作您的 RemoveHandler 成员函数模板可以解决这个问题:

 template<class Functor>
 void RemoveHandler(const Functor &oldFunc)
 {
     for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
     {
         if((*it) == oldFunc)
         {
             callbacks.erase(it);
             break;
         }
     }
 }

在这里,oldFunc 可以保持其实际类型,而不会被“包装”在 boost::函数

See Boost.Function FAQ for an explanation : Why can't I compare boost::function objects with operator== or operator!= ?.

Boost.Functions only provides comparison of a boost::function with an arbitrary function object. I believe that making your RemoveHandler member function template could fix the issue :

 template<class Functor>
 void RemoveHandler(const Functor &oldFunc)
 {
     for(std::vector<callbackFunction>::iterator it = callbacks.begin(); it != callbacks.end(); it++)
     {
         if((*it) == oldFunc)
         {
             callbacks.erase(it);
             break;
         }
     }
 }

Here, oldFunc gets to keep its actual type without being 'wrapped' in a boost::function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文