Reputation: 639
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;
}
Upvotes: 4
Views: 284
Reputation: 346
This would be a comment to paweldac answer but I've not enough reputation.
A better lambda would be initialized using 'this' in the capture list (see http://en.cppreference.com/w/cpp/language/lambda):
int doSomething(int a, int b)
{
auto func = [this](int a, int b) -> int { return add2num(a,b); };
return worker(func, a, b);
}
Additionally, in this way the lambda is initialized every time doSomething
is called. As you do not need this you can consider a way to initialize func
just once.
Upvotes: 0
Reputation: 4369
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.
Upvotes: 4
Reputation: 12259
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.
Upvotes: 4
Reputation: 2778
One possible way, using std::bind and std::function (C++11):
#include <iostream>
#include <functional>
using namespace std::placeholders;
class ABC
{
private:
int x = 3;
int add2num(int a, int b)
{
return a+b+x;
}
int worker(std::function<int(int, int)> fun, int a, int b)
{
return fun(a, b);
}
public:
int doSomething(int a, int b)
{
return worker(std::bind(&ABC::add2num, this, _1, _2), a, b);
}
};
int main()
{
ABC test;
std::cout << test.doSomething(3,5) << std::endl;
return 0;
}
Available on Ideone.
Output: 11
Upvotes: 1
Reputation: 1184
Adapted your code snippet to use lambda functions
#include <iostream>
#include <functional>
using namespace std;
class ABC{
private:
int x =3;
int add2num(int a, int b){
return a+b+x;
}
int worker(std::function<int(int, int)> fun, int a, int b){
return fun(a,b);
}
public:
int doSomething(int a, int b){
auto func = [&](int a, int b) -> int { return add2num(a,b); };
return worker(func, a, b);
}
};
int main() {
ABC test;
cout << test.doSomething(3,5) << endl;
return 0;
}
Here is ideone version: https://ideone.com/cupxaB
Upvotes: 1