真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++11Lambda表達式-創(chuàng)新互聯(lián)

1. Lamda 表達式介紹

lambda表達式:也就是匿名函數(shù),也可以稱作閉包(Closure),字面意義是沒有名字的函數(shù)。它可以很方便地讓我們隨手定義函數(shù),并把函數(shù)當做參數(shù),給其他函數(shù)調(diào)用。這樣的代碼寫起來很簡潔,讀起來也直觀。

創(chuàng)新互聯(lián)建站專注于銅鼓企業(yè)網(wǎng)站建設,響應式網(wǎng)站開發(fā),商城網(wǎng)站定制開發(fā)。銅鼓網(wǎng)站建設公司,為銅鼓等地區(qū)提供建站服務。全流程定制制作,專業(yè)設計,全程項目跟蹤,創(chuàng)新互聯(lián)建站專業(yè)和態(tài)度為您提供的服務

舉例1:對序列{0,11,3,19,22,7,1,5}如何從小到大排序呢?,可以通過定義匿名函數(shù)的方式實現(xiàn)。

#include 
#include#includeusing namespace std;

int main()
{vectorvec {0,11,3,19,22,7,1,5};
	auto f =[](int a, int b)
	{return  ab從大到小排序
	};
	sort(vec.begin(),vec.end(),f);
}
  • sort第3個參數(shù),傳入的就是匿名函數(shù),這樣的寫法相比原始的c++要靈活簡潔很多。
2 Lambda表達式語法

在這里插入圖片描述

  • 首先需要寫一個方括號[ ], 里面可以傳入捕獲變量的形式或者為空
  • 然后是()包起來的參數(shù)列表
  • 然后是->并跟著返回值類型
  • 最后是函數(shù)的實現(xiàn)主體body

舉例2:

auto f = [](int a, int b) ->int {return a+b;
};
cout<< f(1,2)<
>>3
  • 方括號[ ]里面是空的,表示不捕獲外圍的變量
  • 這里lambda的返回值int 是可以忽略的,因為編譯器可通過return a+b以及參數(shù)類型,自行推斷它的返回類型。所以可以等價于如下:
auto f = [](int a, int b){return a+b;
};
cout<< f(1,2)<

一般情況下,不指定 lambda 表達式的返回值,編譯器會根據(jù) return 語句自動推導返回值的類型,但需要注意的是 labmda表達式不能通過列表初始化自動推導出返回值類型。

// ok,可以自動推導出返回值類型
auto f = [](int i)
{return i;
}

// error,不能推導出返回值類型
auto f1 = []()
{return {1, 2};	// 基于列表初始化推導返回值,錯誤
}

2.1 變量捕獲(Capture Cluse)
  • 變量捕獲就是方括號部分,作用是讓我們匿名函數(shù)可以訪問,甚至修改函數(shù)外部的變量,
  • [ ]中可以指定一些外圍的變量,這樣在匿名函數(shù)內(nèi)部就可以訪問這些變量。如果是空的[]表示不捕獲任何變量。
  • 如果變量名前面有引用符號&,表示按引用捕獲,可以修改外部變量的值。如果不加引用符號&,就表示按值捕獲,不能修改外圍變量的值

舉例3:

int N =100, M =10;

auto g = [N,&M](int i)
{M=20;
	return N*i;
}

cout<< g(10)<< endl;
cout<< M<< endl;

輸出

>>1000   // 100*10
>>20     // 匿名函數(shù)內(nèi)部M賦值為20

注:這里N是沒有加&號,只能訪問,不能修改。如果嘗試給N賦值編譯器會報錯

[&]

按引用捕獲:如果捕獲的語句只有引用符號:[&],表示所有的變量都按引用捕獲,即可以修改外圍變量的值。

[=]

按值捕獲: 如果捕獲語句為[=], 表示所有變量都按值捕獲。

[&,=N]

可以單獨指定一些變量按值捕獲,其他變量都按引用捕獲。[&,=N],這種寫法表示按值捕獲變量N,其他變量按引用捕獲。

[this]

可以用this捕獲當前實例的指針,在c++17之后,還可以用[*this]按值捕獲該實例。

舉例

#include#includeusing namespace std;

class Test
{public:
    void output(int x, int y)
    {auto x1 = [] {return m_number; };                      // error
        auto x2 = [=] {return m_number + x + y; };             // ok
        auto x3 = [&] {return m_number + x + y; };             // ok
        auto x4 = [this] {return m_number; };                  // ok
        auto x5 = [this] {return m_number + x + y; };          // error
        auto x6 = [this, x, y] {return m_number + x + y; };    // ok
        auto x7 = [this] {return m_number++; };                // ok
    }
    int m_number = 100;
};
  • x1:錯誤,沒有捕獲外部變量,不能使用類成員 m_number
  • x2:正確,以值拷貝的方式捕獲所有外部變量
  • x3:正確,以引用的方式捕獲所有外部變量
  • x4:正確,捕獲 this 指針,可訪問對象內(nèi)部成員
  • x5:錯誤,捕獲 this 指針,可訪問類內(nèi)部成員,沒有捕獲到變量 x,y,因此不能訪問。
  • x6:正確,捕獲 this 指針,x,y
  • x7:正確,捕獲 this 指針,并且可以修改對象內(nèi)部變量的值
int main(void)
{int a = 10, b = 20;
    auto f1 = [] {return a; };                        // error
    auto f2 = [&] {return a++; };                     // ok
    auto f3 = [=] {return a; };                       // ok
    auto f4 = [=] {return a++; };                     // error
    auto f5 = [a] {return a + b; };                   // error
    auto f6 = [a, &b] {return a + (b++); };           // ok
    auto f7 = [=, &b] {return a + (b++); };           // ok

    return 0;
}
  • f1:錯誤,沒有捕獲外部變量,因此無法訪問變量 a
  • f2:正確,使用引用的方式捕獲外部變量,可讀寫
  • f3:正確,使用值拷貝的方式捕獲外部變量,可讀
  • f4:錯誤,使用值拷貝的方式捕獲外部變量,可讀不能寫
  • f5:錯誤,使用拷貝的方式捕獲了外部變量 a,沒有捕獲外部變量 b,因此無法訪問變量 b
  • f6:正確,使用拷貝的方式捕獲了外部變量 a,只讀,使用引用的方式捕獲外部變量 b,可讀寫
  • f7:正確,使用值拷貝的方式捕獲所有外部變量以及 b 的引用,b 可讀寫,其他只讀

在匿名函數(shù)內(nèi)部,需要通過 lambda 表達式的捕獲列表控制如何捕獲外部變量,以及訪問哪些變量。默認狀態(tài)下 lambda 表達式無法修改通過復制方式捕獲外部變量,如果希望修改這些外部變量,需要通過引用的方式進行捕獲。

2.2 使用mutable修改按值捕獲的外部變量

使用 lambda 表達式捕獲列表捕獲外部變量,如果希望去修改按值捕獲的外部變量,那么應該如何處理呢?這就需要使用mutable選項,被mutable修改是lambda表達式就算沒有參數(shù)也要寫明參數(shù)列表,并且可以去掉按值捕獲的外部變量的只讀(const)屬性。

int a = 0;
auto f1 = [=] {return a++; };              // error, 按值捕獲外部變量, a是只讀的
auto f2 = [=]()mutable {return a++; };     // ok

最后再剖析一下為什么通過值拷貝的方式捕獲的外部變量是只讀的:

  • lambda表達式的類型在C++11中會被看做是一個帶operator()的類,即仿函數(shù)。
  • 按照C++標準,lambda表達式的operator()默認是const的,一個const成員函數(shù)是無法修改成員變量值的。

mutable選項的作用就在于取消 operator () 的 const 屬性

因為 lambda 表達式在 C++ 中會被看做是一個仿函數(shù),因此可以使用std::function和std::bind來存儲和操作lambda表達式:

#include#includeusing namespace std;

int main(void)
{// 包裝可調(diào)用函數(shù)
    std::functionf1 = [](int a) {return a; };
    // 綁定可調(diào)用函數(shù)
    std::functionf2 = bind([](int a) {return a; }, placeholders::_1);

    // 函數(shù)調(diào)用
    cout<< f1(100)<< endl;
    cout<< f2(200)<< endl;
    return 0;
}

對于沒有捕獲任何變量的 lambda 表達式,還可以轉(zhuǎn)換成一個普通的函數(shù)指針

using func_ptr = int(*)(int);
// 沒有捕獲任何外部變量的匿名函數(shù)
func_ptr f = [](int a)
{return a;  
};
// 函數(shù)調(diào)用
f(1314);
2.2 其他特性(c++14后)

支持在捕獲語句中定義新變量

在c++14之后,可以在捕獲語句中定義新的變量,并且初始化,這些變量無需出現(xiàn)在匿名函數(shù)外圍環(huán)境中

void foo()
{int N=100,M=10;
	auto g = [N,&M,K=5](int i)
	{M = 20;
		cout<< K<< endl;
		return N*i;
	};
	
	cout<

在匿名函數(shù)中,引入了一個新的變量K,并且給它賦值5,然后再函數(shù)主體中打印它

參數(shù)類別支持auto類型
[](auto a, auto b) {return a+b;}
在c++14新增的功能,參數(shù)列表支持auto類型,這讓匿名函數(shù)變得更通用,這樣只要支出加號類型的變量都可以利用該匿名函數(shù)。

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


分享題目:C++11Lambda表達式-創(chuàng)新互聯(lián)
文章來源:http://weahome.cn/article/jeeds.html

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部