类成员函数作为函数参数出现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 }

 

posted @ 2018-09-18 14:01  life_limbo  阅读(18229)  评论(2编辑  收藏  举报