// 須傳入指向函數的指標 int ff1( int(*fp)(int) ) { return fp(5); }
可以如下使用沒有問題
// 符合 ff1 所要求的規格 int Backf(int i) { return i * 5; }
int main() { // 一般用法 cout << ff1(Backf) << endl; // 採用 Lambda 的用法 cout << ff1([](int c)->int {return c * 2; }) << endl; return 0; }
但 ff1() 用 Lambda 為參數的用法,只限沒有「擷取子句」(Capture Clause),它就會像一般函數一樣,若有擷取子句編譯時就會有錯誤訊息
int main() { int i = 10; cout << ff1([i](int c)->int {return c * 2 + i; }) << endl; /*
有錯誤訊息: 無法將引數 1 從 'main::<lambda_02198bfdd2c666dbefc4a599da39b9cb>'
轉換為 'int (__cdecl *)(int)'
*/ return 0; }
主要在有擷取子句的 Lambda 相當於一個函數物件(function object)的用法,因此上例的有擷取子句的 Lambda 相當於如下的 class
class Lambda_Obj { int m_i; public: // Constructor Lambda_Obj(int i) { m_i = i; } int operator()(const int c) const { return c * 2 + m_i; } };
為了能因應各種型別,ff1() 須改成 template function 的樣式
// 參數須傳入 int(*fp)(int) 的樣式 template<typename F> int ff2(F fp) { return fp(5); }
這樣使用上就沒問題了
int main() { // 一般用法 cout << ff2(Backf) << endl; // 採用無 擷取子句 Lambda 的用法 cout << ff2([](int c)->int {return c * 2; }) << endl; // 採用有 擷取子句 Lambda 的用法 int i = 10; cout << ff2([i](int c)->int {return c * 2 + i; }) << endl; // Lambda_Obj 的用法 Lambda_Obj Func_Obj(10); cout << ff2(Func_Obj) << endl; return 0; }
Lambda 參考資料:
http://blog.gtwang.org/programming/lambda-expression-in-c11/
https://zh.wikipedia.org/wiki/%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B0
沒有留言:
張貼留言