Вопрос строго о std::function, а не boost::function. Дополнительную информацию см. В разделе "Обновление" в нижней части этого вопроса, особенно в том, что в нем нет возможности сравнивать непустые объекты std::function по стандарту С++ 11.
Шаблон класса С++ 11 std::function отлично подходит для поддержки набора обратных вызовов. Например, можно хранить их в vector и вызывать их, когда это необходимо. Однако сохранение этих объектов и разрешение на регистрацию представляется невозможным.
Позвольте мне указать, представьте себе этот класс:
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()
};
Пример использования сценария:
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);
}
Довольно ясно, как можно реализовать функцию Register(). Однако как бы реализовать реализацию Unregister(). Скажем, что контейнер, содержащий объекты функции, vector<std::function<void()>>. Как вы найдете конкретный объект функции, который передается в вызов Unregister()? std::function действительно содержит перегруженный operator==, но это только тесты для пустого объекта функции (т.е. он не может использоваться для сравнения двух непустых объектов функции, чтобы увидеть, ссылаются ли они на один и тот же фактический вызов).
Буду признателен за любые идеи.
Update:
Идеи до сих пор в основном состоят из добавления файла cookie, который должен быть связан с каждым объектом std::function, который можно использовать для его регистрации. Я надеялся на то, что не является экзогенным для самого объекта std::function. Кроме того, существует много путаницы между std::function и boost::function. Вопрос строго о объектах std::function и не boost::function.
Кроме того, вы не можете сравнивать два непустых объекта std::function для равенства. Они всегда будут сравнивать не равные по стандарту. Таким образом, ссылки в комментариях к решениям, которые делают именно это (и использовать объекты boost::function для загрузки), явно противоречат этому вопросу.