2017-02-21 218 views
1

这是我精简的程序,我试图使用函数变量在运行时修改类功能。所以 - 我声明使用std::function模板和与兼容签名函数myFunc成员变量m_func如何将成员函数赋值给使用std :: function定义的成员变量?

#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); 
} 

但是,编译器(克++ 4.8.4与-std = C++ 11选项)给我一个错误长输出,说template argument deduction/substitution failed和更多...

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

+0

@nwp - 我不会介意你是否关闭它...谢谢 – HEKTO

回答

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

成员函数指针有一个隐含的this指针,需要在他们的签名的第一个参数传递。或者使用std::bind先绑定,

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

或使用lambda。

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

如果你想在成员函数被调用当前对象上,然后你想:

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

我想你错过了一个占位符。 –

+0

@ RichardJ.RossIII:我确实,谢谢! –

4

非静态成员函数指针不能被分配到std::function直接。这个问题的一般解决方法是将this指针捆绑成这样的拉姆达:

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; 
}; 
+0

谢谢!我无法使'myFunc'成为静态的,因为在实际中它需要访问一堆成员变量 – HEKTO

1

正如@Kerrek SB上面提到的,你可以使用std::bind

然而,最好使用lambda,因为它可以有更少的开销:

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

至于开销 - 你是指在这个任务期间的开销,还是在'm_func'调用期间的开销? (我真的关心第二个案例) – HEKTO

+0

其实我会说他们两个。 – Telokis

相关问题