1

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;
    }
}
5
  • Helpful reading: isocpp.org/wiki/faq/pointers-to-members#macro-for-ptr-to-memfn Commented Apr 3, 2017 at 1:06
  • 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? Commented Apr 3, 2017 at 1:20
  • @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 ^^ Commented Apr 3, 2017 at 1:38
  • 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. Commented Apr 3, 2017 at 1:45
  • 2
    Possible duplicate of C++ Call Pointer To Member Function Commented Aug 7, 2019 at 4:09

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Same error ): E0109 expression preceding parentheses of apparent call must have (pointer-to-) function type line 39 UserEvents.cpp
It worked, thanks! Could you enlighten me on why the this-> is necessary?
Well, that's the syntax of the language. C++ has two operators, ".*" and "->*", created to access class member by pointer. Here's some article about them: msdn.microsoft.com/en-us/library/k8336763.aspx The ubiquitous "*" operator just doesn't work with class member pointers.
Member pointer can be used with any pointer to class instance, not just this. Hence the need to explicitly mention which class instance should be used.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.