Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a function in a class as a parameter to another function in the same class in C++11?

Tags:

c++

c++11

lambda

The following minimalist codes are used to illustrate my question. Those codes do not compile. How can I use lambda expression or std::bind to pass a function member as a parameter? Many thanks for your help

#include <iostream>

using namespace std;
class ABC{
private:
    int x =3;
    int add2num(int a, int b){
        return a+b+x;
    }

    int worker(int &fun(int a, int b), int a, int b){
        return fun(a,b);
    }
public:
    int doSomething(int a, int b){
        return worker(add2num, a, b);
    }
};

int main() {
    ABC test;
    cout << test.doSomething(3,5) << endl;
    return 0;
}
like image 854
drbombe Avatar asked Dec 24 '22 22:12

drbombe


2 Answers

Using lambdas and templates:

#include <iostream>
#include <functional>

using namespace std;
class ABC{
private:
    int x =3;
    int add2num(int a, int b){
        return a+b+x;
    }

   template<class functor_t>
   int worker(const functor_t& fun, int a, int b){
       return fun(a,b);
   }

public:
   int doSomething(int a, int b) {
     return worker([this](int a, int b){ return add2num(a, b); }, a, b);
   }

};

int main() {
    ABC test;
    cout << test.doSomething(3,5) << endl;
    return 0;
}

Or, without lambdas but using std::bind:

   int doSomething(int a, int b) {
     namespace ph = std::placeholders;

     return worker(std::bind(&ABC::add2num, this, ph::_1, ph::_2), a, b);
   }

The rest of the code doesn't need to be touch, since worker is still a template, and thus accepts any callable type.

like image 158
Peregring-lk Avatar answered Apr 28 '23 12:04

Peregring-lk


You can achieve your goal without a lambda or std::bind like this:

#include <iostream>

using namespace std;
class ABC{
private:
    int x =3;
    int add2num(int a, int b){
        return a+b+x;
    }

    int worker(int (ABC::*fun)(int a, int b), int a, int b){
        return (this->*fun)(a,b);
    }
public:
    int doSomething(int a, int b){
        return worker(&ABC::add2num, a, b);
    }
};

int main() {
    ABC test;
    cout << test.doSomething(3,5) << endl;
    return 0;
}

Compare this code against yours to see differences.

Here you can read more about pointers to members etc.

like image 45
Michał Walenciak Avatar answered Apr 28 '23 13:04

Michał Walenciak