C++11 lambda
阿新 • • 發佈:2019-02-11
捕獲欄位:空,=,&
空:不能訪問外部變數
=:按值訪問外部變數,[var]按值訪問var,[=]按值訪問所有變數
&:引用方式訪問外部變數,[&var]引用訪問var變數,[&]引用訪問所有變數
組合[=,&var]能夠按照引用訪問var和按值訪問所有變數
特殊情況:lambda函式在某個成員函式裡面時,[this]和[=]可以訪問這個成員函式所能訪問的物件
理解捕獲的概念:
// declaring_lambda_expressions2.cpp // compile with: /EHsc /W4 #include <functional> #include <iostream> int main() { using namespace std; int i = 3; int j = 5; // The following lambda expression captures i by value and // j by reference. function<int (void)> f = [i, &j] { return i + j; };//宣告定義f的時候,使用i的值傳入,j的引用 // Change the values of i and j. i = 22; j = 44; // Call f and print its result. cout << f() << endl; //output:3+44=47 }
1、獲取變數型別
- #include <typeinfo.h>
- int a = 1;
- typeid(a).name();
2、lambda表示式用法
C++11 提供了對匿名函式的支援,稱為 Lambda 函式(也叫 Lambda 表示式)。Lambda 表示式把函式看作物件。Lambda 表示式可以像物件一樣使用,比如可以將它們賦給變數和作為引數傳遞,還可以像函式一樣對其求值。Lambda 表示式本質上與函式宣告非常類似。- [capture](parameters)->return-type{body}
- //例如
- [](int x, int y) -> int { int z = x + y;
- int main(){
- int a = 1;
- int b = 2;
- auto lambda = []{return a + b;};
- //error! 空捕獲列表,無法使用作用域內其他變數
- auto lambda = [](int a, int b){return a + b;};
- //success
- auto lambda = [=]{return a + b;};
- //success, 值傳遞
- auto lambda = [=]{a++; b++; return a + b;};
- //error! 值傳遞無法修改變數值
- auto lambda = [&]{a++; b++; return a + b;};
- //success, 引用傳遞
- auto lambda = [&a, b]{a++; b++; return a + b;};
- //error, 變數a引用傳遞,變數b值傳遞,故b不可修改
- }
3、將lambda表示式作為函式引數傳遞
想要使lambda作為引數,首先要明白他的型別,但是auto無法作為函式引數型別,使用1中獲取型別方法輸出為【Z4mainEUlvE_23】,根本不是型別,查閱資料,只能使用template模板來實現。- template<typename T>
- struct isFunctor : std::false_type {
- };
- template<typename L, typename R, typename... Args>
- struct isFunctor<R (L::*)(Args...)> : std::true_type {
- };
- template<typename L>
- struct isLambda : isFunctor<decltype(&L::operator())> {
- };
- template<typename L>
- std::enable_if<isLambda<L>::value> check(L lambda) {
- cout << " lambda(1, 2) = " << lambda(1, 2) << lambda(1, 2);
- }
- int main() {
- auto fun = [&](int a, int b) {
- a++;
- b++;
- cout << a <<"."<< b << endl;
- return pow(a, b);
- };
- check(fun);
- return 0;
- }
- //輸出為: 2.3
- // 2.3
- // lambda(1, 2) = 88
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
//lambda基礎
void lambda_one();
//sort中lambda例項
void lambda_two();
//lambda函式遞迴
void lambda_three();
int main()
{
lambda_one();
lambda_two();
lambda_three();
getchar();
return 0;
}
void lambda_one()
{
cout<<endl <<"------------沒有函式引數的lambda---------------------"<<endl;
auto fun = [](){};
auto fun1 = [](){cout <<"fun1"<<endl;};
fun1();
cout<<endl <<"------------for_each中使用簡單的lambda----------------"<<endl;
std::vector<int> v(3,5);
for_each(v.begin(),v.end(),[](int num){ cout << num << "\t";});
cout<<endl <<"------------設定lambda的返回值型別--------------------"<<endl;
cout <<[](double a, double b){return a + b;}(1.4,2.5)<<endl;
cout <<[](double a, double b)->int{return a + b;}(1.4,2.5)<<endl;
cout<<endl <<"------------lambda中的傳值----------------------------"<<endl;
int x = 10;
int y = 100;
[=](double a, double b)mutable->int
{
cout <<"lambda:"<<(x = 100) << "\t" <<(y = 10)<<endl;
return a + b;
}(1.4,2.5);
cout<<"main:" << x <<"\t"<< y <<endl;
cout<<endl <<"------------lambda中的傳引用--------------------------"<<endl;
[&x,&y](double a, double b)mutable->int
{
cout <<"lambda:"<<(x = 100) << "\t" <<(y = 10)<<endl;
return a + b;
}(1.4,2.5);
cout<<"main:" << x <<"\t"<< y <<endl;
cout<<endl <<"------------lambda中的傳引用和引用傳遞------------------"<<endl;
//等號必須寫在前面,或者也可以[x,&y].
//=表示,除了&y,其他所有的外部變數都可以按照值傳遞進行訪問。
[=,&y](double a, double b)mutable->int
{
cout <<"lambda:"<<(x = 100) << "\t" <<(y = 10)<<endl;
return a + b;
}(1.4,2.5);
cout<<"main:" << x <<"\t"<< y <<endl;
}
void lambda_two()
{
//1.sort排序
cout <<endl<<"------------sort排序中使用lambda------------------------"<<endl;
int a[8] = {6,8,3,4,9,2,7,1};
sort(begin(a),end(a),[](const int &a ,const int &b)->bool{return a < b;});
for_each(begin(a),end(a),[](const int &num){cout << num << "\t";});
cout <<endl<<"---------------------------------------------------------"<<endl;
}
void lambda_three()
{
//2. (lambda遞迴)3個數返回最大的兩個數的和
cout <<endl<<"------------lambda遞迴-----------------------------------"<<endl;
function<int(int,int,int)> f = [&f](int a,int b,int c)->int
{
if (a<= b && a <= c)
{
return b + c;
}
return f(b,c,a);
};
cout << f(4,5,6)<<endl;
}