The easiest way is to use std::function
and std::bind
.
#include <functional>
#include <array>
derived_class object1;
derived_class object2;
std::array< std::function<int(int, int)>, 2> >
arr = {{ std::bind(&derived_class::function1, &object1)
, std::bind(&derived_class::function2, &object1)}};
// and so on
Note that object1
and object2
have been bound by address. You need to keep them alive as long as the bound functions are alive. If you just write object1
in the bind
expression a copy of the object will be stored in the bound function and no scope problems will occur.
C++03 A complete example with a hand-rolled, single-purpose binder-type:
#include <iostream>
struct base
{
virtual void f0() { std::cout << "f0 base" << std::endl; }
virtual void f1() { std::cout << "f1 base" << std::endl; }
};
struct derived : base
{
void f0() { std::cout << "f0 derived" << std::endl; }
void f1() { std::cout << "f1 derived" << std::endl; }
};
// typedef for a Pointer to a member function
// of base that accepts arguments and returns void
typedef void (base::*MemberPtrType)(void);
// we pack a pointer to a class and a pointer to a member function together
struct binder
{
MemberPtrType ptr;
base* base;
// shortcut to call this thing, you might also want
// to have an overload of operator() and a result_type typedef
void call()
{ ((base)->*(ptr))(); }
};
int main()
{
base b;
derived d;
// initialize a 4 element array of binder, the first argument is the function,
// the second is the object to call it on
//
// remember that b and d need to be alive as long as
// you want to call something in this array
binder arr[4] = { {&base::f0, &b}, {&base::f1, &b},
{&base::f0, &d}, {&base::f1, &d}};
// now walk through the array and call each
for(binder* begin = arr; begin != arr + 4; ++begin)
{
begin->call();
}
return 0;
}