这是我的精简程序,我试图在运行时使用函数变量来修改类功能。所以 - 我使用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
变量?
答案 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);};