user2381422
user2381422

Reputation: 5805

How do I create an array of method pointers in C++?

How do I create an array of method pointers in C++?

The problem is, although these methods have the same signature, they are in different classes. Those classes inherit from one same class.

For example:

class A : public Base {
    virtual bool work();
}

class B : public Base {
    virtual bool work();
}

And I need to create an array of pointers to the methods A::work and B::work, in another class.

Edit 1:

I decided to go with Useless's suggestion, option 1:

vector<Base*> units;
Base *a = new A();
Base *b = new B();
units.push_back(a);
units.push_back(b);

Thanks

Upvotes: 1

Views: 3162

Answers (4)

Useless
Useless

Reputation: 67723

First option:

if the different methods are just a implementations of the same virtual method in different subclasses, ie. Base looks like:

class Base {
public:
    virtual bool work() = 0;
}

Then all of your method pointers have type bool (Base::*)(). In this case, your problem is choosing an object to call this method on, so you presumably have a container of Base* pointers with different dynamic types.


Second option:

your classes are really unrelated, and you just want to call some function with signature bool (*)() without worrying about the object.

In this case, either:

  1. your classes and their instances are really irrelevant and you could just use static methods
    • so just use free functions
  2. you need an instance but don't know what type it is when choosing the function

    • you need a functor which can capture the instance, and provide a compatible nullary call operator. As has already been suggested, std::function<bool()> is the simplest way. For example, you could populate a vector like so:

      std::vector<std::function<bool()>> fvec() {
          A a;
          B b;
          std::vector<std::function<bool()>> funcs;
          funcs.push_back( [a]() { return a.work(); } );
          funcs.push_back( [b]() { return b.work(); } );
          return funcs;
      }
      

      Note that the a and b objects are captured by value in the lambdas, so it no longer matters whether A and B have any kind of inheritance relationship.

Upvotes: 5

user529758
user529758

Reputation:

Well, technically you can create an array of pointers to member functions, although as others suggested, you probably shouldn't. This works:

class Base {
    public:
    bool work()
    {
        return true;
    }
};

int main()
{
    bool (Base::*arr[2])() = { &Base::work, &Base::work };
    return 0;
}

Upvotes: 1

Edward A
Edward A

Reputation: 2310

You can use a combination of std::function and std::bind both of which are found in <functional>.

Example:

#include <functional>
#include <vector>

class Base
{
public:
    virtual bool work() = 0;
};

class A : public Base
{
public:
    bool work() {return true;}
};

class B : public Base
{
public:
    bool work() {return false;}
};

int main()
{
    std::vector<std::function<bool(void)>> list;

    A t1;
    B t2;

    list.push_back(std::bind(&A::work, t1));
    list.push_back(std::bind(&B::work, t2));

    for (auto& i : list)
    {
        printf("%s\n", (i()) ? "true" : "false");
    }
}

Outputs:

true
false

Upvotes: 2

Salgar
Salgar

Reputation: 7775

create an array (std::vector) of std::function

With std::function you can use std::bind to make a function pointer to any member function. For member functions you have to also bind to a specific instance of the object.

Here is an example of how to use it. std::function to member function

If you do not have c++11 access, you can do the same with boost::bind and boost::function

Upvotes: 4

Related Questions