std :: funkcja jako wywołanie zwrotne, czy można wyrejestrować?
Pytanie jest ściśle związane zstd::function
i nieboost::function
. ZobaczAktualizacja sekcja na dole tego pytania, aby uzyskać więcej szczegółów, zwłaszcza część o tym, że nie można porównać niepustegostd::function
obiekty według standardu C ++ 11.
C ++ 11std::function
szablon klasy jest świetny do utrzymywania kolekcji wywołań zwrotnych. Można je przechowywać wvector
na przykład i przywołaj je, gdy zajdzie taka potrzeba. Jednak utrzymanie tych obiektów i umożliwienie wyrejestrowania wydaje się niemożliwe.
Pozwól mi być konkretnym, wyobraź sobie tę klasę:
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()
};
Scenariusz użycia próbki:
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);
}
Jest dość jasne, jakRegister()
funkcja może zostać zaimplementowana. Jak jednak pójść na temat wdrożeniaUnregister()
. Powiedzmy, że pojemnik zawierający obiekty funkcji tovector<std::function<void()>>
. Jak znalazłbyś konkretny obiekt funkcji przekazany doUnregister()
połączenie?std::function
nie dostarcza przeciążeniaoperator==
, ale testuje tylko pusty obiekt funkcji (tzn. nie można go użyć do porównania dwóch niepustych obiektów funkcji, aby sprawdzić, czy oba odnoszą się do tego samego rzeczywistego obiektu)wezwanie).
Byłbym wdzięczny za wszelkie pomysły.
Aktualizacja:
Dotychczasowe pomysły polegają głównie na dodaniu pliku cookie, który będzie powiązany z każdymstd::function
obiekt, którego można użyć do wyrejestrowania go. Liczyłem na coś, co nie jest egzogenicznestd::function
sam obiekt. Poza tym wydaje się, że istnieje duże zamieszaniestd::function
iboost::function
. Pytanie jest ściśle związane zstd::function
obiekty inie boost::function
przedmioty.
Nie można również porównać dwóch niepustychstd::function
przedmioty dla równości. Zawsze będą porównywać nierównomierne według standardu. Tak więc łączy komentarze do rozwiązań, które to właśnie robią (i używająboost::function
obiekty do rozruchu) są wyraźnie błędne w kontekście tego pytania.