Sign in to follow this  

C++ Function Pointer Casting

This topic is 1194 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey,

    I'm trying to set up a function pointer so that ANY function can be passed to it as long as it's the same signature.

 

Example

 
// Define a simple function pointer
typedef void (*FuncPointer)();
 
void someFunc()
{
}
 
int main()
{
    FuncPointer func = someFunc;
 
    func();
}
 
// This works no prob
 
 
// Now here is what I want to do
class A
{
public:
    void foo();
};
 

// Define a simple function pointer
typedef void (*FuncPointer)();

 
int main()
{
    // This is what I want to work
    FuncPointer func = A::foo;
 
    // I want it to work without having to define a function pointer like this
   typedef void (A::*FunctionPointer)()
 
/*
    IS THIS POSSIBLE?
*/
 
    func();
}
 

Share this post


Link to post
Share on other sites

Consider the hypothetical call to func() in your last example; what is the value of the this pointer inside A::foo() once func() is called? In other words, which object do you expect the member function to be called on?

 

The moral of the story is: you expect it work work as long as the functions have the same signature, but someFunc() and A::foo() are fundamentally different.

Share this post


Link to post
Share on other sites

I know this, let me clarify

class A
{
public:
    void foo();
};
 

// Define a simple function pointer
typedef void (*Func)();

 
int main()
{
    A obj;

    // This is what I want to work
    Func func = obj.foo;
 
    func();
}
 

I want to be able to have access to that object inside the function that gets called from the function pointer so that I don't have to have some sort of global reference to 'obj'

 

 

you can't typecast it to a 'Func', it gives an error as well.

 

The whole reason is I have a button class which has a function pointer that it calls when the button is clicked, and the function that gets passed to it is a 'void (*Func)()'.  I want to be able to have access to the class that holds that button without having to create some static/global variable to get access to it.

Edited by Muzzy A

Share this post


Link to post
Share on other sites

I want to be able to have access to that object inside the function that gets called from the function pointer so that I don't have to have some sort of global reference to 'obj'

 

You don't, not with standard function pointers like this. Member function pointers are different beasts. In the old C days you would idiomatically do this kind of thing by having your code take a void* "user data" pointer, which would then be passed along to the callback function, so that your callback could have non-global state, which I suppose is what you are trying to achieve. Something like set_callback(func_ptr, &foo) and then use the pointer to your class instance from the callback parameters. In C++, you probably want to use the modern C++ features like std::function, bind, lambdas, etc... which handle all of this and more.

Share this post


Link to post
Share on other sites

The example would become:
 

using FuncWrapper = std::function<void()>;

void someFunc()
{
}

class A
{
public:
    void foo();
};
 
int main()
{
    // free function
    FuncWrapper func = someFunc;
    func();

    // member via lambda
    A obj;
    func = [&](){ obj.foo(); };
    func();

    // member via std::bind (there's also a Boost version if your compiler is ancient)
    func = std::bind(std::mem_fn(&A::foo), &obj);
    func();
}
You can also have std::function, lambdas, or std::bind using arguments and return values by spelling out the signature, e.g. std::function<result_type(param_type1, param_type2)> and then adding the forwarding params to the lambda or the placeholders (std::_1, std::_2, etc.) to std::bind.

 

mem_fn is not needed there, bind already handles the case of member function pointers. 

    func = std::bind(&A::foo, &obj);

is sufficient. Also, let's not forget to add the necessary header include at the start...

#include <functional>
Edited by Washu

Share this post


Link to post
Share on other sites

This topic is 1194 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this