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 :
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.
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.
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.
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);
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!