Reputation: 5805
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
Reputation: 67723
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.
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:
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
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
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
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