Heim >Backend-Entwicklung >C++ >Wie kann ich Funktionen mit unterschiedlichen Signaturen in einer Karte in C speichern?
In C können Sie auf Szenarien stoßen, in denen Sie Funktionen mit unterschiedlichen Signaturen in einer Datenstruktur speichern müssen. Angenommen, Sie haben einen Kartencontainer, der einen Zeichenfolgenschlüssel und eine generische Methode als Wert akzeptiert. Um dies zu ermöglichen, sollten Sie den folgenden Ansatz in Betracht ziehen:
C stellt den Typ std::any für die Typlöschung bereit. Sie können std::any verwenden, um einen Funktionszeiger oder einen Lambda-Ausdruck in einem Container zu speichern, ohne seinen genauen Typ anzugeben. Um die gespeicherte Funktion aufzurufen, müssen Sie sie jedoch explizit in den richtigen Typ umwandeln.
Um die explizite Umwandlung zu umgehen, können Sie einen Vorlagenoperator-Operator definieren( ) für eine benutzerdefinierte Wrapper-Klasse, die das gespeicherte std::any-Objekt als Parameter verwendet. Mit diesem Operator können Sie die gespeicherte Funktion aufrufen, ohne dass eine explizite Umwandlung erforderlich ist.
Hier ist eine Beispielimplementierung einer solchen Wrapper-Klasse:
template<typename Ret> struct AnyCallable { AnyCallable() {} template<typename F> AnyCallable(F&& fun) : AnyCallable(std::function(std::forward<F>(fun))) {} template<typename ... Args> AnyCallable(std::function<Ret(Args...)> fun) : m_any(fun) {} template<typename ... Args> Ret operator()(Args&& ... args) { return std::invoke(std::any_cast<std::function<Ret(Args...)>>(m_any), std::forward<Args>(args)...); } std::any m_any; };
In Bei dieser Implementierung umschließt die AnyCallable-Klasse das gespeicherte std::any-Objekt und stellt einen Operator() bereit, der die Funktion mit dem angegebenen aufruft Argumente.
Mit der AnyCallable-Klasse können Sie eine Karte erstellen, die Funktionen mit unterschiedlichen Signaturen speichert und diese dynamisch aufruft:
void foo(int x, int y) { /* ... */ } void bar(std::string x, int y, int z) { /* ... */ } std::map<std::string, AnyCallable<void>> map; map["foo"] = &foo; map["bar"] = &bar; map["foo"](1, 2); map["bar"]("Hello", 1, 2);
Beachten Sie, dass Sie beim Aufruf der gespeicherten Funktionen auf typgelöschte Weise die richtigen Argumenttypen explizit übergeben müssen. Typkonflikte führen zu einer std::bad_any_cast-Ausnahme.
Das obige ist der detaillierte Inhalt vonWie kann ich Funktionen mit unterschiedlichen Signaturen in einer Karte in C speichern?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!