Вопрос строго о 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
для загрузки), явно противоречат этому вопросу.