The question is strictly about std::function and not boost::function. See the Update section at the bottom of this question for more details, especially the part about it not being possible to compare non-empty std::function objects per the C++11 standard.
The C++11 std::function class template is great for maintaining a collection of callbacks. One can store them in a vector, for example and invoke them when need be. However, maintaining these objects and allowing for unregistration seems to be impossible.
Let me be specific, imagine this class:
class Invoker
{
public:
void Register(std::function<void()> f);
void Unregister(std::function<void()> f);
void InvokeAll();
private:
// Some container that holds the function objects passed to Register()
};
Sample usage scenario:
void foo()
{
}
int main()
{
std::function<void()> f1{foo};
std::function<void()> f2{[] {std::cout << "Hello\n";} };
Invoker inv;
// The easy part
// Register callbacks
inv.Register(f1);
inv.Register(f2);
// Invoke them
inv.InvokeAll();
// The seemingly impossible part. How can Unregister() be implemented to actually
// locate the correct object to unregister (i.e., remove from its container)?
inv.Unregister(f2);
inv.Unregister(f1);
}
It is fairly clear how the Register() function can be implemented. However, how would one go about implementing Unregister(). Let's say that the container that holds the function objects is vector<std::function<void()>> . How would you find a particular function object that is passed to the Unregister() call? std::function does supply an overloaded operator==, but that only tests for an empty function object (i.e., it cannot be used to compare two non-empty function objects to see if they both refer to the same actual invocation).
I would appreciate any ideas.
Update:
Ideas so far mainly consist of the addition of a cookie to be associated with each std::function object that can be used to unregister it. I was hoping for something that is not exogenous to the std::function object itself. Also, there seems to be much confusion between std::function and boost::function. The question is strictly about std::function objects, and not boost::function objects.
Also, you cannot compare two non-empty std::function objects for equality. They will always compare non-equal per the standard. So, links in the comments to solutions that do just that (and use boost::function objects to boot) are patently wrong in the context of this question.