Maison >développement back-end >C++ >Comment stocker des fonctions avec différentes signatures dans une carte en C ?

Comment stocker des fonctions avec différentes signatures dans une carte en C ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-13 12:32:02700parcourir

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

Stocker des fonctions avec différentes signatures dans une carte

En C , vous pouvez rencontrer des scénarios dans lesquels vous devez stocker des fonctions avec différentes signatures dans une structure de données. Supposons que vous disposiez d’un conteneur de cartes qui accepte une clé de chaîne et une méthode générique comme valeur. Pour rendre cela possible, envisagez l'approche suivante :

Type Erasure et Any Type

C fournit le std::any type pour l'effacement de type. Vous pouvez utiliser std::any pour stocker un pointeur de fonction ou une expression lambda dans un conteneur sans spécifier son type exact. Cependant, pour appeler la fonction stockée, vous devez la convertir explicitement dans le type correct.

Surcharge d'opérateur pour l'invocation de fonction

Pour surmonter la conversion explicite, vous pouvez définir un opérateur de modèle opérateur( ) sur une classe wrapper personnalisée qui prend l'objet std::any stocké comme paramètre. Cet opérateur vous permet d'invoquer la fonction stockée sans avoir besoin d'un casting explicite.

Exemple d'implémentation

Voici un exemple d'implémentation d'une telle classe wrapper :

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

Dans Cette implémentation, la classe AnyCallable encapsule l'objet std::any stocké et fournit un Operator() qui appelle la fonction avec les arguments spécifiés.

Exemple d'utilisation

Avec la classe AnyCallable, vous pouvez créez une carte qui stocke les fonctions avec différentes signatures et invoquez-les dynamiquement :

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

Considérations

Notez que lorsque vous invoquez les fonctions stockées d'une manière effacée, vous devez transmettre le bon types d'arguments explicitement. Les incompatibilités de types entraîneront une exception std::bad_any_cast.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn