Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass a class method as a parameter to another function and later call it, preferably making the variable class method signature explicit?

If I have a class that needs to call a parent class method with a class method as parameter I can do it with std::function + std::bind as shown below:

class A {
    void complexMethod(std::function<void()> variableMethod) {
        // other stuff ...
        variableMethod();
        // some other stuff..
    }
}

class B : public A {
    void myWay() {
        // this and that
    }

    void otherWay() {
        // other and different
    }

    void doingSomething() {
        // Preparing to do something complex.
        complexMethod(std::bind(&B::myWay, this));
    }

    void doingAnotherThing() {
        // Different preparation to do some other complex thing.
        complexMethod(std::bind(&B::otherWay, this));
    }
}

How would I need to change the above code to implement the same thing using templates instead of std::function + std::bind?

And how about lambdas instead of std::function + std::bind? I still want to call B:myWay() and B::otherWay() but using lambdas. I don't want to substitute B:myWay() and B::otherWay() with lambdas.

Is there any implementation technique (one of the above or some other) were I would be able to make variableMethod return type and parameters explicit? How would I do it? Let's say the signature of variableMethod is:

    bool variableMethod(int a, double b);

Which technique is recommended? Why (speed, flexibility, readility...)?

like image 650
Rsevero Avatar asked Oct 23 '25 02:10

Rsevero


1 Answers

Template + lambda solution:

struct A
{
    template <typename F>
    void runA(F func)
    {
        cout << 1 << endl;
        func();
        cout << 3 << endl;
    }
};

struct B : A
{
    int number = 2;

    void runnable() { cout << number << endl; }

    void runB()
    {
        cout << 0 << endl;
        runA([this]() { runnable(); });
        cout << 4 << endl;
    }
};

int main()
{
    B variable;
    variable.runB();
}

In order to take a function as template parameter, just take in a template type of that function like above. lambdas can be used instead of bind to make things easier (this is passed to lambda captures list).

Explicitly declaring the arguments:

void run_func(std::function<bool(int, double)> func)
{
    bool b = func(10, 10.01);
}

std::function allows you to define your arguement and return types like above.

like image 107
Shahriar Avatar answered Oct 25 '25 18:10

Shahriar