如何将类中的函数作为参数传递给C ++ 11中同一个类中的另一个函数?

时间:2016-12-28 10:25:38

标签: c++ c++11 lambda

以下极简主义代码用于说明我的问题。那些代码不编译。如何使用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;
}

5 个答案:

答案 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一次。