Home >Backend Development >C++ >How can I store functions with varying signatures in a map using C ?

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

Patricia Arquette
Patricia ArquetteOriginal
2024-11-11 21:59:02471browse

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

Storing Functions with Different Signatures in a Map

In this code, we aim to create a map that stores functions with varying signatures, leveraging a string as the key and a generic method as the value.

Implementing the Map

We utilize the std::any library to achieve this. By type-erasing the function types into a container, we can create a template operator() function to invoke them dynamically. However, it's crucial to specify exact argument matches at the call site to avoid std::bad_any_cast exceptions.

Example Implementation

Consider the following code snippet:

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

This code demonstrates how to store and invoke functions with different signatures within a map, utilizing type erasure and a template operator().

The above is the detailed content of How can I store functions with varying signatures in a map using C ?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn