// 須傳入指向函數的指標
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
沒有留言:
張貼留言