Comparing boost functions - function signature?

2019-08-20 19:27发布

问题:

To start of, I have read the other topics on the subject here on SO and I've read the boost faq aswell and I still do not feel I have an answer to my problem below.

I want to have a sort-of delegate system using function wrappers like boost::function. I solve this by storing boost::function objects in a vector. The problem comes with a method like UnregisterCallback(), where one expects to compare the supplied callback with the ones stored and remove it if found. From what I've gathered around the webs, it is because boost function objects are not compareable.

Yet, using a template as per #2, I can make it work as I want it too. See example below:

#include <vector>
#include <algorithm>
#include "boost/function.hpp"

typedef boost::function<void (int)> Callback;

class CallbackHandler
{
public:
    void AddCallback(const Callback& callback)
    {
        mCallbacks.push_back(callback);
    }

    // #1: dosnt work
    void RemoveCallback(const Callback& callback)
    {
        mCallbacks.erase(std::find(mCallbacks.begin(), mCallbacks.end(), callback));
    }

    // #2: works
    template <typename T>
    void RemoveCallback(const T& callback)
    {
        mCallbacks.erase(std::find(mCallbacks.begin(), mCallbacks.end(), callback));
    }

private:
    std::vector<Callback> mCallbacks;

};


void testCB(int i)
{
}


int _tmain(int argc, _TCHAR* argv[])
{
    CallbackHandler handler;
    handler.AddCallback(testCB);
    handler.RemoveCallback(testCB);

    return 0;
}

But I cannot/do not want to use a templated function, so I was wondering, since it obviously works there must be a valid function signature to make it work right? Yet I cannot for the life of me figure out what it is, or why the template version works while the other dosnt.

Any help is appreciated.

Thanks

回答1:

boost::function objects can be compared to other functors and function pointers, but not to other boost::function objects (see reference here). When you call the templated version, T becomes a void(*)(int) function pointer, so operator== is valid, can see that the types are the same, and simply compares the underlying function pointer in the boost::function object with the function pointer you passed in. For the non-templated version you are comparing two boost::function objects, which is not valid.