以下极简主义代码用于说明我的问题。那些代码不编译。如何使用lambda表达式或std::bind
将函数成员作为参数传递?非常感谢您的帮助
#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;
}
答案 0 :(得分:4)
你可以在没有lambda或std::bind
的情况下实现你的目标:
#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;
}
将此代码与您的代码进行比较以查看差异。
Here你可以阅读更多关于成员指针的信息。
答案 1 :(得分:4)
使用lambdas和模板:
#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;
}
或者,没有lambda但使用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);
}
其余代码不需要触摸,因为worker
仍然是模板,因此接受任何可调用类型。
答案 2 :(得分:1)
一种可能的方法,使用std :: bind和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;
}
可在Ideone上找到。
输出: 11
答案 3 :(得分:1)
修改您的代码段以使用lambda函数
#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;
}
以下是ideone版本:https://ideone.com/cupxaB
答案 4 :(得分:0)
这是对paweldac答案的评论,但我的声誉不够。
更好的lambda将使用&#39;这个&#39;来初始化。在捕获列表中(参见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);
}
此外,通过这种方式,每次调用doSomething
时都会初始化lambda。由于您不需要这个,您可以考虑一种方法来初始化func
一次。