类成员函数作为函数参数出现error C3867:非标准语法;请使用“&”来创建指向成员的指针
有的时候一个泛函可能会采用函数或函数对象(functor)做参数,这时候我们可能想要使用类的成员函数来做参数,但是这时候会出现error C3867: 非标准语法;请使用 "&" 来创建指向成员的指针,比如下面例子:
1 1 #include <iostream> 2 2 using namespace std; 3 3 class TestC 4 4 { 5 5 private: 6 6 double a, b; 7 7 public: 8 8 TestC(double a_,double b_):a(a_),b(b_){} 9 9 double testFun(double x); 10 10 }; 11 11 template<class Func> 12 12 double testTemplateFun(double input, Func proccess) 13 13 { 14 14 return proccess(input); 15 15 } 16 16 17 17 int main() 18 18 { 19 19 double a = 10; 20 20 TestC t(2, 3); 21 21 cout << "输出结果为:" << testTemplateFun(a, t.testFun); 22 22 system("pause"); 23 23 return 0; 24 24 } 25 25 26 26 double TestC::testFun(double x) 27 27 { 28 28 return a*x + b; 29 29 }
这时候我们按照提示将t.testFun前面加上&又会出现error C2276: “&”: 绑定成员函数表达式上的非法操作,那么这到底是什么错误?
其实这里是因为类的成员函数默认带有一个this指针参数,那么它作为泛函的参数其实就不匹配了,因为泛函中的Func类型并没有this指针,所以我们可以把TestC类中的testFun(double x)函数声明为静态(static)的,这样就不带有this指针;但是静态的函数又不能访问非静态的成员,像这里TestC的testFun函数访问了非静态的成员变量a,b,就会出错,那要怎么办?这里其实就是相当于泛函中要求单参函数,而使用的是双参函数,可以自己定义一个适配类,适配双参函数为单参,如下例:
1 1 #include <iostream> 2 2 using namespace std; 3 3 class TestC 4 4 { 5 5 private: 6 6 double a, b; 7 7 public: 8 8 TestC(double a_,double b_):a(a_),b(b_){} 9 9 double testFun(double x); 10 10 }; 11 11 template<class Func> 12 12 double testTemplateFun(double input, Func proccess) 13 13 { 14 14 return proccess(input); 15 15 } 16 16 class TestCAdapter 17 17 { 18 18 private: 19 19 TestC *t; 20 20 public: 21 21 TestCAdapter(TestC *t_):t(t_){} 22 22 double operator()(double x); 23 23 }; 24 24 int main() 25 25 { 26 26 double a = 10; 27 27 TestC t(2, 3); 28 28 //cout << "输出结果为:" << testTemplateFun(a, t.testFun) << endl; 29 29 TestCAdapter ad(&t); 30 30 cout << "输出结果为:" << testTemplateFun(a, ad) << endl; 31 31 system("pause"); 32 32 return 0; 33 33 } 34 34 35 35 double TestC::testFun(double x) 36 36 { 37 37 return a*x + b; 38 38 } 39 39 40 40 double TestCAdapter::operator()(double x) 41 41 { 42 42 return t->testFun(x); 43 43 }