std :: function как callback, возможна ли отмена регистрации?
Вопрос строго оstd::function
и нетboost::function
, УвидетьОбновить раздел в нижней части этого вопроса для более подробной информации, особенно в части о том, что нельзя сравнивать непустыеstd::function
объекты в соответствии со стандартом C ++ 11.
C ++ 11std::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==
, но это проверяет только пустой объект функции (то есть его нельзя использовать для сравнения двух непустых объектов функции, чтобы увидеть, ссылаются ли они на один и тот же фактический объект).вызов).
Буду признателен за любые идеи.
Обновить:
Идеи до сих пор в основном состоят из добавления файла cookie, связанного с каждымstd::function
объект, который можно использовать для отмены регистрации. Я надеялся на то, что не является экзогенным дляstd::function
сам объект Кроме того, кажется, что существует большая путаница междуstd::function
а такжеboost::function
, Вопрос строго оstd::function
объекты ине boost::function
объекты.
Также нельзя сравнивать два непустыхstd::function
объекты для равенства. Они всегда будут сравнивать неравные по стандарту. Так, ссылки в комментариях на решения, которые делают именно это (и используютboost::function
объекты для загрузки) явно неправильно в контексте этого вопроса.