Mr. Smith
Mr. Smith

Reputation: 4506

function pointer from one class to member function of any class

I'm having difficulties defining a function pointer that can point to any member function (not just member functions for the specified class).

For instance, C++ forces me to specify the class that a function pointer to a member function would point to:

typedef void (Foo::*MyFunctionPointerTypeName)(int);

but what if the class member function that this function pointer is going to point to isn't in Foo? How then would I write this, or what alternative approach could I use?


Update: For anyone looking for a quick answer on how to accomplish this with a C++11 std::function (as tutorials on the subject seem to assume alot of the reader):

Definition (from within Foo):

std::function<void(int)> _fun;

Binding (from any class):

objFoo->_fun = std::bind(&SomeOtherClass::memberFunction, 
    this, std::placeholders::_1);

Calling it (from within Foo)

if(_fun != nullptr) _fun(42);

If your function has no parameters, you can remove std::placeholders::_1. And if your function has two parameters you'll need to also add std::placeholders::_2 as a parameter to std::bind. Similarly for three parameters, four parameters, etc.

Upvotes: 0

Views: 854

Answers (2)

Nicol Bolas
Nicol Bolas

Reputation: 473302

You cannot write a member pointer that could point to a member of any class. Remember: one of the arguments of a member pointer is the class instance itself. And pointers are typed, so the type of its arguments is very much a part of the pointer's type.

You can use std::function however, which can store all sorts of callables. How you would actually call it (ie: what parameters you give it) depends on your needs, as you haven't explained what you're trying to do.

Upvotes: 1

PaperBirdMaster
PaperBirdMaster

Reputation: 13320

Use inheritance:

#include <iostream>

struct Foo {};

struct Bar : public Foo
{
    int F0()
    {
        return 0;
    }
};

struct Baz : public Foo
{
    int F1()
    {
        return 1;
    }    
};

int main(int argc, char **argv)
{
    int (Bar::*pF0)() = &Bar::F0;
    int (Baz::*pF1)() = &Baz::F1;
    int (Foo::*pointer1)() = static_cast<int (Foo::*)()>(pF0);
    int (Foo::*pointer2)() = static_cast<int (Foo::*)()>(pF1);

    Bar r;
    Baz z;

    // Pointer to Foo member function calling Bar member function        
    std::cout << (r.*pointer1)() << '\n';
    // Pointer to Foo member function calling Baz member function
    std::cout << (z.*pointer2)() << '\n';

    return 0;
}

Output:

0
1

Hope it helps.

Upvotes: 1

Related Questions