program miseria
program miseria

Reputation: 23

Storing and accessing different member functions in a table

I would like to save various member functions in a table, similar to the Sol2 library.

Member functions of different classes with different return values and different parameters are given. Is it possible to store these member functions in a table under C++ and execute them later? I suspect the Sol2 library (c++ lua binding) stores function pointers in a std::tuple. But I haven't figured out how to execute the functions then.

Here is sample code for a better understanding of the question:

// various classes with different member functions
struct classA
{
    void function_a() {}
    bool function_b( int nValue1 ) {}
    int function_c( int nValue1, int nValue2 ) {}
};

struct classB
{
    int function_a() {}
    void function_b( int nValue1 ) {}
    bool function_c( int nValue1, int nValue2 ) {}
};


struct FunctionTable
{
    // function to store a memberfunction with a object instance
    template<class T, class ... Args>
    void addFunction( std::string strFunctionName, T * t, Args ... args )
    {
        // how to store the function pointer?
    }

    // function for returning the stored function pointer
    ? ? ? get(std::string strFunctionName)
    {
        return m_mapFunctions[strFunctionName];
    }
    // how to store the pointers in a container, e. g. std::map?
    std::map<std::string, ? ? ? > m_mapFunctions;
};

void main2()
{
    classA a;
    classB b;

    FunctionTable functionTable;

    // store different member functions in to the function table with a name as index
    functionTable.addFunction( "classA_function_a", &a, &classA::function_a );
    functionTable.addFunction( "classA_function_b", &a, &classA::function_b );
    functionTable.addFunction( "classA_function_c", &a, &classA::function_c );

    functionTable.addFunction("classB_function_a", &b, &classB::function_a);
    functionTable.addFunction("classB_function_b", &b, &classB::function_b);
    functionTable.addFunction("classB_function_c", &b, &classB::function_c);


    // Example calls

    auto functionA = functionTable.get("classA_function_a");
    functionA();

    auto functionB = functionTable.get("classA_function_b");
    bool bReturnValue = functionB(99);

    auto functionC = functionTable.get("classA_function_c");
    int nReturnValue = functionC(23, 24);

}

Does anyone have an idea or a hint how this can be realized?

Upvotes: 2

Views: 285

Answers (1)

eerorika
eerorika

Reputation: 238341

C++ is a statically typed language. Maps are homogeneous: All elements of a map have exactly the same type.

A pointer to a function of one type is a different type from a pointer to another function type. Type of a function is determined by its argument and return types. As such, it is not possible to store pointers to functions of different argument lists or return types in the same map.

There are however techniques for "type erasure", which allows simulation of dynamic typing. C++ standard library comes with two heterogeneous wrappers: std::variant and std::any. Variant is an implementation of a tagged union. It can be used to store an object from a pre-defined list of types. any is a type safe wrapper for void*. It can store an object of any type. So, a map of variant or any might be what you're looking for.

They are only low level tools though, and for more featured heterogeneous processing, there are existing libraries such as Boost.Hana.

Upvotes: 4

Related Questions