C++匿名函數的使用


c++匿名函數使用方法

1、匿名函數的使用

匿名函數的基本語法為:

//[捕獲列表](參數列表)->返回類型{函數體}
int main()
{
	auto Add = [](int a, int b)->int {
		return a + b;
	};
	std::cout << Add(1, 2) << std::endl;
	return 0;
}

上述代碼便會輸出3,這就是匿名函數的使用方法。

注意點:一般情況下,編譯器可以自動推斷出lambda表達式的返回類型,所以我們可以不指定返回類型,即:

//[捕獲列表](參數列表){函數體}
int main()
{
	auto Add = [](int a, int b) {
		return a + b;
	};
	std::cout << Add(1, 2) << std::endl;
	return 0;
}

但是如果函數體內有多個return語句時,編譯器無法自動推斷出返回類型,此時必須指定返回類型

2、什么是捕獲列表?

試圖在Lambda內使用外部變量是錯誤的,例如:

#include <iostream>

int main()
{
	int c = 12;
	auto Add = [](int a, int b)->int {
		return c;
	};
	std::cout << Add(1, 2) << std::endl;
	return 0;
}

但是有些時候我們需要使用外部變量,所以需要使用捕獲列表,上述代碼改寫成一下形式便可以通過編譯。

#include <iostream>

int main()
{
	int c = 12;
	auto Add = [c](int a, int b)->int {
		return c;
	};
	std::cout << Add(1, 2) << std::endl;
	return 0;
}

但是如果你更改一下lambda表達式中代碼塊的內容,比如在上述代碼中添加一句

c = a;

這樣又會無法編譯通過了,因為你的c是按值傳遞的,所以要將捕獲列表改成

[&c](int a, int b)->int{……};

這樣c的值便是按引用傳遞了,便可以進行修改。

補充知識:

  1. 如果捕獲列表為[&],則表示所有的外部變量都按引用傳遞給lambda使用
  2. 如果捕獲列表為[=],則表示所有的外部變量都按值傳遞給lambda使用
  3. 匿名函數構建的時候對於按值傳遞的捕獲列表,會立即將當前可以取到的值拷貝一份作為常數,然后將該常數作為參數傳遞,即:
int main()
{
	int c = 12;
    //Add構建的時候實際是:[12](int a,int b)->int{}
	auto Add = [c](int a, int b)->int {
		return c;
	};
	std::cout << Add(1, 2) << std::endl;
	return 0;
}

到此,匿名函數(Lambda表達式)的基礎使用方法就介紹完畢了

3、一些”廢話“

在這一小節中,我們會提一些和Lambda有關的知識。

3.1、介紹Lambda

一個Lambda表達式表示一個可調用的代碼單元,我們可以將它理解為一個未命名的內聯函數。和任何函數類似,一個Lambda表達式具有一個返回類型,一個參數列表和一個函數體,但和普通函數不一樣的是Lambda表達式可能定義在函數內部。我們可以忽略Lambda表達式的參數列表和返回類型,但不可以忽略捕獲列表和函數體

//
//這是正確的(忽略了參數列表和返回類型)
//
//為什么沒有指定返回類型還可以返回整數值?
//因為你的函數體有return語句,它可以推斷出來
auto f = []{ return 1 + 2; };

3.2、Lambda捕獲列表

[] 空捕獲列表,Lambda不能使用所在函數中的變量。
[names] names是一個逗號分隔的名字列表,這些名字都是Lambda所在函數的局部變量。默認情況下,這些變量會被拷貝,然后按值傳遞,名字前面如果使用了&,則按引用傳遞
[&] 隱式捕獲列表,Lambda體內使用的局部變量都按引用方式傳遞
[=] 隱式捕獲列表,Lanbda體內使用的局部變量都按值傳遞
[&,identifier_list] identifier_list是一個逗號分隔的列表,包含0個或多個來自所在函數的變量,這些變量采用值捕獲的方式,其他變量則被隱式捕獲,采用引用方式傳遞,identifier_list中的名字前面不能使用&。
[=,identifier_list] identifier_list中的變量采用引用方式捕獲,而被隱式捕獲的變量都采用按值傳遞的方式捕獲。identifier_list中的名字不能包含this,且這些名字面前必須使用&。

參考資料:《C++ Primer(第五版)》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM