Home > Back-end >  About std::function usage
About std::function usage

Time:12-25

as the below code, I don't want so many "if else"

class A
{
public:
    void f0()
    {
        cout << "f0" << endl;
    }
    void f1()
    {
        cout << "f1" << endl;
    }
    void f2()
    {   
        cout << "f2" << endl;
    }
    //..... 
};


class B
{
public:
    void f(int n)
    {
        //vector< function<void()> > f_v {obj_a.f0, obj_a.f1, obj_a.f2}; //this usage is not correct
        if (n == 0)
            obj_a.f0();
        else if (n == 1)
            obj_a.f1();
        else if (n == 2)
            obj_a.f2();
        //.....
    }
private:
    A obj_a;
};

I want to create a vector and use std::function to avoid using so many if-else , like vector< function<void()> > f_v {obj_a.f0, obj_a.f1, obj_a.f2}; but it was not a correct usage. How could I do?

CodePudding user response:

You can use std::function with a lambda wrapper,

vector<function<void()>> f_v {[this]() { obj_a.f0(); }, 
                              [this]() { obj_a.f1(); }, 
                              [this]() { obj_a.f2(); }};
f_v[n]();

or use pointer-to-members directly,

vector<void (A::*)()> f_v { &A::f0, &A::f1, &A::f2 };
(obj_a.*f_v[n])();

CodePudding user response:

If you are aiming at speed and you know the number of methods, avoid using std::vector for the extra indirection. Use std::array as it will hit cache with the current object.

For this simple case, you don't necessarily need to use std::function, which is a very heavy object to call. You can use pointers to members like this:

#include <iostream>
#include <array>

using namespace std;

class A
{
public:
    void f0()
    {
        cout << "f0" << endl;
    }
    void f1()
    {
        cout << "f1" << endl;
    }
    void f2()
    {   
        cout << "f2" << endl;
    }
    //..... 
};


class B
{
public:
    B() {
        fn[0] = &A::f0;
        fn[1] = &A::f1;
        fn[2] = &A::f2;
    }
    void f(int n)
    {
        ((obj_a).*(fn[n]))();
    }
private:
    using Fn = void (A::*)();
    std::array<Fn,3> fn;
    A obj_a;
};

Code: https://godbolt.org/z/z4KqKvn99

CodePudding user response:

Your approach seems correct. You just need to std::bind those member functions like

class B{
std::vector <std::function <void()>> m_vec_functs; 
...
B(const A& a)
{
 m_vec_functs.push_back(std::bind(&A::f0, a));
 m_vec_functs.push_back(std::bind(&A::f1, a));
}

void f(unsigned int n)
{
 m_vec_functs[n];
}
...
};

Then you can access each individual function by its index, knowing their order.

CodePudding user response:

I usually use typedef , you can try this

void f1(){
    cout << "f1\n";
}
void f2(){
    cout << "f2\n";
}
typedef void (*fp)();

int main(){
    vector<fp> a = {f1, f2};
    a[0]();
    a[1]();
    return 0;
}
  • Related