Maison >développement back-end >C++ >Comment puis-je stocker des fonctions avec des signatures variables dans une carte en utilisant C ?

Comment puis-je stocker des fonctions avec des signatures variables dans une carte en utilisant C ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-11 21:59:02473parcourir

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

Stockage de fonctions avec différentes signatures dans une carte

Dans ce code, nous visons à créer une carte qui stocke des fonctions avec différentes signatures, en utilisant une chaîne comme clé et une méthode générique comme valeur.

Implémentation de la carte

Nous utilisons la bibliothèque std::any pour y parvenir. En effaçant les types de fonctions dans un conteneur, nous pouvons créer une fonction modèle Operator() pour les invoquer dynamiquement. Cependant, il est crucial de spécifier des correspondances d'arguments exactes sur le site d'appel pour éviter les exceptions std::bad_any_cast.

Exemple d'implémentation

Considérez l'extrait de code suivant :

#include <any>
#include <functional>
#include <map>
#include <string>
#include <iostream>

using namespace std::literals;

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

void foo(int x, int y)
{
    std::cout << "foo" << x << y << std::endl;
}

void bar(std::string x, int y, int z)
{
    std::cout << "bar" << x << y << z << std::endl;
} 

int main()
{
    std::map<std::string, AnyCallable<void>> map;
    
    map["foo"] = &foo;      //store the methods in the map
    map["bar"] = &bar;
    
    map["foo"](1, 2);       //call them with parameters I get at runtime
    map["bar"]("Hello, std::string literal"s, 1, 2);
    try {
        map["bar"]("Hello, const char *literal", 1, 2); // bad_any_cast
    } catch (std::bad_any_cast&) {
        std::cout << "mismatched argument types" << std::endl;
    }
    map["bar"].operator()<std::string, int, int>("Hello, const char *literal", 1, 2); // explicit template parameters
    
    return 0;
}

Ce code montre comment stocker et appeler des fonctions avec différentes signatures dans une carte, en utilisant l'effacement de type et un opérateur de modèle().

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