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(&开发者_如何学GoHasCallback::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.
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
.
精彩评论