Zack Lee
Zack Lee

Reputation: 3074

How to pass lamda as a function pointer argument of member function?

I learned how to pass member functions to another member function as a function pointer argument.

Now, I'm trying to pass lamda as a function pointer argument of member function.

My Code:

#include <iostream>

using namespace std;

class Test
{
public:
    int add(int a, int b)
    {
        return a + b;
    }
    int sub(int a, int b)
    {
        return a - b;
    }
    typedef int (Test::*funcPtr)(int a, int b);
    int myFunc(funcPtr func, int a, int b)
    {
        return (this->*func)(a, b);
    }
    void setup()
    {
        cout << myFunc(&Test::add, 5, 3) << endl;
        cout << myFunc(&Test::sub, 5, 3) << endl;
        cout << myFunc([](int a, int b) {return a * b;}, 5, 3) << endl; //ERROR!!!
    }
};

int main()
{
    Test test;
    test.setup();
}

Result:

Error: : No viable conversion from lambda to 'Test::funcPtr' (aka 'int (Test::*)(int, int)')

Expected Result:

8
2
15

How should I correct my code so I can get the expected result?

Upvotes: 0

Views: 114

Answers (1)

Oblivion
Oblivion

Reputation: 7374

one option is making your functions static and then use std::function as type:

using funcType = std::function<int(int, int)>;
int myFunc(funcType func, int a, int b)
{
    return func(a, b);
}

void setup()
{
    cout << myFunc(Test::add, 5, 3) << endl;
    cout << myFunc(Test::sub, 5, 3) << endl;
    cout << myFunc([](int a, int b) {return a * b;}, 5, 3) << endl;
}

Live

Thanks to @holyBlackCat the other option is using regular function pointer(member functions need to be static):

typedef int (*funcPtr)(int a, int b);
//or:
//using funcPtr =  int (*)(int a, int b);
int myFunc(funcPtr func, int a, int b)
{
    return (*func)(a, b);
}

and also template:

template<typename funcType>
int myFunc(funcType func, int a, int b)
{
    return func(a, b);
}
void setup()
{
    cout << myFunc(Test::add, 5, 3) << endl;
    cout << myFunc(Test::sub, 5, 3) << endl;
    cout << myFunc([](int a, int b) {return a * b;}, 5, 3) << endl;
}

regular function pointer live, template live


EDIT

The examples provided above are working only with static member function. To invoke non-static member functions you can use pointer to member function type

using funcPtr = int(Test::*)(int a, int b);
int myFunc(funcPtr func, int a, int b)
{
    return invoke(func, this, a, b);
}

//..
// call:
cout << myFunc(&Test::add, 5, 3) << endl;

pointer to non-static member function live

Upvotes: 3

Related Questions