1
votes

I'm programming a Discrete Event Simulator (DES) where events will be user programmed functions. I have a Class called UserEvents and a private member function called Add

    void Add(const void *Parameters, void *ReturnValue);

I'm trying to make a vector that would store the following struct:

 typedef struct FunctionPointerAlias { std::string FAlias; void(UserEvents::*FPointer)(const void*, void*); };

Based on a string, I want to call different functions. Thus switch would be nice but switch can't handle strings (and I don't want to hash my strings). So I made a vector with a struct (string Alias, FunctionPointer) and then I'll iterate over my vector looking for the user's inputed string, recovering the corresponding function pointer and calling it.

All user functions should be of type void, receiving parameters and returning values through void* pointers as such:

void UserEvents::Add(const void *Parameters, void *ReturnValue)
{
    int *A = (int*)Parameters;
    int *B = A;
    B++;

    int *C = (int*)ReturnValue;
    *C = *A + *B;

    //memcpy(ReturnValue, &C, sizeof(int));
    return;
}

(TL;DR) The problem lies when I try to call the function pointed by the function pointer. I get the error "Expression preceding parentheses of apparent call must have (pointer-to-) function type" on the line right above return in the "Add" if.

    void UserEvents::Choose(const std::string Alias, const void *Parameters, void *ReturnValue)
{
    if (Alias == "Example")
    {
        // *ReturnValue = Function(Parameters)
        return;
    }

    if (Alias == "Add") {
        void (UserEvents::*FunctionPointer)(const void*, void*) = &UserEvents::Add;
        (*FunctionPointer)(Parameters, ReturnValue);
        return;
    }
}
2
Your code doesn't seem to make much sense. Is Add meant to be a member function or not? If not, why is it? If so, how are you expecting to invoke it without an object on which to invoke it?David Schwartz
@DavidSchwartz, Add is meant to be a member function. I'm not too sure on what you mean by invoke it without an object on which to invoke it? I'm new to C++ and decided to use this uni project to learn it ^^Pedro
Honestly, it seems you don't understand what a member function is. For example, if you have a class called "Instrument", it might have a member function called "Play" which plays some particular instrument. But you have to have an instrument you want to play. You can't just call the Play function to play nothing in particular. A class member functions makes some particular class instance do something. There has to be some class instance.David Schwartz
Possible duplicate of C++ Call Pointer To Member Functionphuclv

2 Answers

3
votes

I think the syntax to invoke that member function by pointer should be e.g.

( this->*FunctionPointer )( Parameters, ReturnValue );

C++ has two operators, .* and ->*, specifically created to access class members by pointer. Here's an article on the topic. The ubiquitous * operator just doesn't work with class member pointers.

0
votes

I didn't understand what you need very well, so I tried to do something general, you should use the pattern in your own class:

#include <iostream>
#include <string>

typedef void(*STR_FUNC)(const void*, void*);

struct FUNCTION_POINTER_ALIAS
{
    std::string FAlias;
    STR_FUNC fn;
};

void FN0(const void *Parameters, void *ReturnValue)
{
    std::cout << *(std::string*) Parameters << " FN0" << std::endl;
}

void FN1(const void *Parameters, void *ReturnValue)
{
    std::cout << *(std::string*) Parameters << " FN1" << std::endl;
}

void FN2(const void *Parameters, void *ReturnValue)
{
    std::cout << *(std::string*) Parameters << " FN2" << std::endl;
}

int main()
{
    FUNCTION_POINTER_ALIAS Items[] = {{"str0", FN0}, {"str1", FN1}, {"str2", FN2}};
    for (int i = 0; i < sizeof(Items) / sizeof(FUNCTION_POINTER_ALIAS); ++i)
        Items[i].fn(&Items[i].FAlias, NULL);
}