Max021
Max021

Reputation: 113

C++ boost::bind and boost::function, class member function callbacks and operator==. What am I doing wrong?

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.

Upvotes: 1

Views: 1072

Answers (1)

icecrime
icecrime

Reputation: 76755

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.

Upvotes: 1

Related Questions