1.Lambda的語法
所謂lambda是一份功能定義式,可以被定義于陳述句(statement)或運算式(expression)內部,因此可以將lambda當作inline函式使用,[]叫做introducer,可以在內部指明一個所謂的capture,用來在lambda內部訪問nonstatic外部物件
- 最簡單的lambda
int main()
{
//定義一個lambda,但沒有進行呼叫
[] {
std::cout << "hello lambda!" << endl;
};
//定義一個lambda并進行呼叫
[] {
std::cout << "hello lambda1!" << endl;
}();
//或者將它傳給一個物件
auto l = [] {
std::cout << "hello lambda1!" << endl;
};
l(); //呼叫
cout << sizeof(l) << endl; //answer = 1
return 0;
}
在lambda introducer和lambda body之間,可以指明引數或mutable,或一份例外明細或attribute specifier以及回傳型別,這些是可有可無的,如果出現了,引數所需的小括號就必須出現
lambda語法
1.[...] {...}
2.[...] (...) mutable throwSpec ->retType {...}
lambda可以擁有引數,指明在小括號內
auto l = [] (const string& s) {
cout << s << endl;
};
l("hello");
lambda不可以是template,必須始終指明所有型別,
lambda也可以回傳某物,但不需要指明回傳型別,該型別會根據回傳值被推匯出來,
int main()
{
// 1.lambda可以回傳某物,不用指明型別,可以自動推導
auto l = [] {
return 123;
};
int ans = l();
cout << ans << endl;
// 2.也可以指明一個回傳型別
auto l2 = []() -> double { //注意()
return 123;
};
double ans2 = l2();
cout << ans2 << endl;
return 0;
}
2.Capture(用以訪問外部作用域)
在lambda最開始的方括號內,可以指明一個capture用來處理外部作用域內未被傳遞為實參的資料:
- [=]意味著外部作用域以by value方式傳遞給lambda,因此當這個lambda被定義時,你可以讀取所有可讀資料,但不能修改
- [&]意味著外部作用域以by reference方式傳遞給lambda,可以對所有資料進行修改,
- 也可以個別指明為by value或者by reference,混合使用,也可以[=, &y]取代[x, &y],意思是y以by reference傳遞,其他實參以by value傳遞,
int main()
{
int x = 0;
int y = 42;
auto l = [x, &y] {
// x以by value形式傳遞, y以by reference方式傳遞
cout << "x: " << x << endl; //0
cout << "y: " << y << endl; //42
//x++; //error
y++; //ok
};
l();
cout << "final y: " << y << endl; //43
return 0;
}
為了得到passing by reference和value的混合體,可以宣告lambda為mutable,意思是以by value傳遞,但是可以在lambda中修改傳入的值,
int main()
{
int x = 0;
int y = 42;
auto l = [x, &y]() mutable {
// x以by value形式傳遞, y以by reference方式傳遞
cout << "x: " << x << endl; //0
cout << "y: " << y << endl; //42
x++; //ok
y++; //ok
};
l();
cout << "final x: " << x << endl; //0
cout << "final y: " << y << endl; //43
return 0;
}
3.Lambda的型別
lambda的型別,是一個不具名的function object(或者說functor),每個lambda運算式的型別是獨一無二的,因此如果想根據該型別宣告物件,可以借助template或者auto,如果實在需要寫下這個型別,可以借助decltype().例如將lambda作為hash function或ordering準則或sorting準則傳給容器,
也可以使用C++STL提供的function<>class template指明一個一般化型別給functional programming使用,這個class template提供了"明確指出函式的回傳型別為lambda"的唯一辦法,
#include <iostream>
#include <functional>
using namespace std;
function<int(int, int)> returnLambda() {
return [](int x, int y) {
return x * y;
};
}
int main()
{
auto lf = returnLambda();
cout << lf(5, 7) << endl;
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/542207.html
標籤:其他
