有的時候一個泛函可能會采用函數或函數對象(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 }