类成员函数作为函数参数/回调函数 出现error C3867

转自:https://blog.csdn.net/liyunxin_c_language/article/details/83188176

 

类成员函数作为函数参数出现error C3867:非标准语法;请使用“&”来创建指向成员的指针

有的时候一个泛函可能会采用函数或函数对象(functor)做参数,这时候我们可能想要使用类的成员函数来做参数,但是这时候会出现error C3867: 非标准语法;请使用 "&" 来创建指向成员的指针,比如下面例子:

 

  1.  
    #include <iostream>
  2.  
    using namespace std;
  3.  
    class TestC
  4.  
    {
  5.  
    private:
  6.  
    double a, b;
  7.  
    public:
  8.  
    TestC(double a_,double b_):a(a_),b(b_){}
  9.  
    double testFun(double x);
  10.  
    };
  11.  
    template<class Func>
  12.  
    double testTemplateFun(double input, Func proccess)
  13.  
    {
  14.  
    return proccess(input);
  15.  
    }
  16.  
     
  17.  
    int main()
  18.  
    {
  19.  
    double a = 10;
  20.  
    TestC t(2, 3);
  21.  
    cout << "输出结果为:" << testTemplateFun(a, t.testFun);
  22.  
    system("pause");
  23.  
    return 0;
  24.  
    }
  25.  
     
  26.  
    double TestC::testFun(double x)
  27.  
    {
  28.  
    return a*x + b;
  29.  
    }


这时候我们按照提示将t.testFun前面加上&又会出现error C2276: “&”: 绑定成员函数表达式上的非法操作,那么这到底是什么错误?

其实这里是因为类的成员函数默认带有一个this指针参数,那么它作为泛函的参数其实就不匹配了,因为泛函中的Func类型并没有this指针,所以我们可以把TestC类中的testFun(double x)函数声明为静态(static)的,这样就不带有this指针;但是静态的函数又不能访问非静态的成员,像这里TestC的testFun函数访问了非静态的成员变量a,b,就会出错,那要怎么办?这里其实就是相当于泛函中要求单参函数,而使用的是双参函数,可以自己定义一个适配类,适配双参函数为单参,如下例:

  1.  
    #include <iostream>
  2.  
    using namespace std;
  3.  
    class TestC
  4.  
    {
  5.  
    private:
  6.  
    double a, b;
  7.  
    public:
  8.  
    TestC(double a_,double b_):a(a_),b(b_){}
  9.  
    double testFun(double x);
  10.  
    };
  11.  
    template<class Func>
  12.  
    double testTemplateFun(double input, Func proccess)
  13.  
    {
  14.  
    return proccess(input);
  15.  
    }
  16.  
    class TestCAdapter
  17.  
    {
  18.  
    private:
  19.  
    TestC *t;
  20.  
    public:
  21.  
    TestCAdapter(TestC *t_):t(t_){}
  22.  
    double operator()(double x);
  23.  
    };
  24.  
    int main()
  25.  
    {
  26.  
    double a = 10;
  27.  
    TestC t(2, 3);
  28.  
    //cout << "输出结果为:" << testTemplateFun(a, t.testFun) << endl;
  29.  
    TestCAdapter ad(&t);
  30.  
    cout << "输出结果为:" << testTemplateFun(a, ad) << endl;
  31.  
    system("pause");
  32.  
    return 0;
  33.  
    }
  34.  
     
  35.  
    double TestC::testFun(double x)
  36.  
    {
  37.  
    return a*x + b;
  38.  
    }
  39.  
     
  40.  
    double TestCAdapter::operator()(double x)
  41.  
    {
  42.  
    return t->testFun(x);
  43.  
    }
posted @ 2019-04-10 14:34  damoying  阅读(473)  评论(0编辑  收藏  举报