Interesting problem. I'm thinking the intent is to avoid the binding actions within main, but to automate the bindings in a class member function.
I picture the intent to be this:
A setState() function is called on an object in response to an event (mouse click, keystroke, etc.) which assigns a desired function to be called in an act() function being called at the frame rate.
@Zereo. Thanks for the intro to <functional> and std::bind.
@rmxhaha. Is this what you're trying to achieve?
Class A: Uses <functional> and std::bind to select the desired member function for the action. The functional is always bound to *this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
#include <iostream>
#include <functional>
using namespace std;
// using functional and bind *this to a member function
class A
{
private:
void patrol(){ cout << "patrol "; }
void run(){ cout << "run "; }
void attack(){ cout << "attack "; }
std::function<void()> actFunc;
public:
void setState(int State )
{
switch(State)
{
case 1: actFunc = std::bind(&A::patrol, *this); break;
case 2: actFunc = std::bind(&A::run, *this); break;
case 3: actFunc = std::bind(&A::attack, *this); break;
default: actFunc = std::bind(&A::patrol, *this); break;
}
}
void act() { actFunc(); }
A(int State) { setState(State); }
};
|
For some reason, I like to see if I can perform a given task using only "elementary" methods. Class B below performs the same task using a regular function pointer to private static class functions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
// using a plain pointer to static class functions. No need to #include<functional>
class B
{
private:
static void patrol(B* pA){ cout << "patrol "; }// these can be called only in class B member functions
static void run(B* pA){ cout << "run "; }
static void attack(B* pA){ cout << "attack "; }
void(*pAct)(B*);// an ordinary function pointer
public:
void setState(int State )
{
switch(State)
{
case 1: pAct = B::patrol; break;
case 2: pAct = B::run; break;
case 3: pAct = B::attack; break;
default: pAct = 0; break;
}
}
void act()
{
if( pAct ) pAct(this);
else cout << "no act specified \n";
}
B(int State) { setState(State); }
};
|
The usage for either class object in main() is the same:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
int main()
{
//
A a(1);// patrol
a.act();
a.setState(2);// run
a.act();
cout << endl;
B b(3);// attack
b.act();
b.setState(1);// patrol
b.act();
cout << endl;
return 0;
}
|
which produces (as hoped for):