I have recently declared similar class to this:
class Foo {
public:
void run();
private:
void foo();
void boo();
void doo();
std::function<void()>getFunction(int);
};
In this example I'd like to get pointer to the member function depending on the passed integer.
void Foo::run(){
std::function<void()> f;
for(int i = 0; i < 3; i++){
f = getFunction(i);
f();
}
}
std::function<void()>Foo::getFunction(int i){
switch(i){
case 0: return foo;
case 1: return Foo::boo;
case 2: return this->*doo;
}
}
All cases cause compiler errors. Adding static to function for case 1 works but I prefer not to use static members.
Is there any way to get these pointers properly without using static keyword?
As an extension to songyuanyao's answer
What about using lambdas? (assuming it's only a matter of being able to call the internal functions and not the function pointers by themselves that are important)
void Foo::run(){
std::function<void()> f;
for(int i = 0; i < 3; i++){
f = getFunction(i);
f();
}
}
std::function<void()> Foo::getFunction(int i) {
switch(i){
case 0: return [this](){this->foo();};
case 1: return [this](){this->boo();};
case 2: return [this](){this->doo();};
}
}
LIVE3
You need to bind an object to call non-static member function with it, in this case it's this. You can use std::bind,
std::function<void()> Foo::getFunction(int i) {
switch(i){
case 0: return std::bind(&Foo::foo, *this); // or std::bind(&Foo::foo, this)
case 1: return std::bind(&Foo::boo, *this); // or std::bind(&Foo::boo, this)
case 2: return std::bind(&Foo::doo, *this); // or std::bind(&Foo::doo, this)
}
}
LIVE1
Or change std::function<void()> to std::function<void(Foo&)>, to match for non-static member function. Then
void Foo::run() {
std::function<void(Foo&)> f;
for(int i = 0; i < 3; i++) {
f = getFunction(i);
f(*this);
}
}
std::function<void(Foo&)> Foo::getFunction(int i) {
switch(i){
case 0: return &Foo::foo;
case 1: return &Foo::boo;
case 2: return &Foo::doo;
}
}
LIVE2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With