如何将成员函数分配给使用std :: function定义的成员变量?

时间:2017-02-21 21:38:41

标签: c++

这是我的精简程序,我试图在运行时使用函数变量来修改类功能。所以 - 我使用m_func模板和具有兼容签名的函数std::function声明成员变量myFunc

#include <functional>
#include <iostream>

struct T
{
  T():m_func([](int){return true;}) {}
  void assign() {m_func = &T::myFunc;}    // <======== Problem is here
  void call(int M) const {std::cout << m_func(M) << std::endl;}
private:
  bool myFunc(int N) {return (N >= 4);}
  using func = std::function<bool(int)>;
  func m_func;
};

int main()
{
  T t;
  t.assign();
  t.call(6);
}

然而,编译器(带有-std = c ++ 11选项的g ++ 4.8.4)给出了一个输出长的错误,说template argument deduction/substitution failed还有更多......

为什么我不能将myFunc函数分配给m_func变量?

4 个答案:

答案 0 :(得分:5)

无法将非静态成员函数指针直接分配给std::function。这个问题的一般解决方案是将this指针绑定到这样的lambda:

void assign() { 
    m_func = [this](int N) { 
        return this->myFunc(N); 
    };
}

在你的情况下,让myFunc静态化似乎更简单。

struct T
{
    T() :m_func([](int) {return true; }) {}
    void assign() { m_func = &T::myFunc; }
    void call(int M) const { std::cout << m_func(M) << std::endl; }
private:
    static bool myFunc(int N) { return (N >= 4); }
//  ^^^^^^ static methods can be assigned to std::function directly
    using func = std::function<bool(int)>;
    func m_func;
};

答案 1 :(得分:3)

如果要在当前对象上调用成员函数,则需要:

m_func = std::bind(&T::myFunc, this, std::placeholders::_1);

答案 2 :(得分:2)

void assign() {m_func = &T::myFunc;}

成员函数指针有一个隐式this指针,需要作为签名中的第一个参数传递。使用std::bind首先绑定它,

void assign() {
    m_func = std::bind(&T::myFunc, this, std::placeholders::_1);
}

或使用lambda表达式(捕获this)。

void assign() {
    m_func = [this](int arg){ return this->myFunc(arg); };
}

答案 3 :(得分:1)

如上文@Kerrek SB所述,您可以使用std::bind

但是,使用lambda会更好,因为它可以减少开销:

m_func = [this] (int N) {return myFunc(N);};