Heim >Backend-Entwicklung >C++ >Wie kann ich Funktionen mit unterschiedlichen Signaturen in einer Karte in C speichern?

Wie kann ich Funktionen mit unterschiedlichen Signaturen in einer Karte in C speichern?

Patricia Arquette
Patricia ArquetteOriginal
2024-11-13 12:32:02729Durchsuche

How can I store functions with different signatures in a map in C  ?

Funktionen mit unterschiedlichen Signaturen in einer Karte 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:

Type Erasure und Any Type

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.

Operatorüberladung für Funktionsaufrufe

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.

Beispielimplementierung

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.

Beispielverwendung

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);

Überlegungen

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn