C++ lambda表達式【學習筆記】

C++ lambda表達式

lambda表達式組成

  • [捕獲列表](參數列表)->返回類型{函數體}
  • 參數列表返回類型可以省略,但捕獲列表函數體必須包含;
  • 捕獲列表通常爲空,返回類型必須使用尾置返回
  • 例:
auto f = []{return 42;};

捕獲列表

  • 只用於局部非static變量
  • 值捕獲:捕獲的變量值是在lambda表達式創建時變量的拷貝,而不是調用時的拷貝
void fcn1(){
	int v1=42;
	auto f=[v1]{return v1;};
	v1=0;
	auto j=f();      //j=42
}
  • 引用捕獲:捕獲的是變量的引用,而不是拷貝。
void fcn2(){
	int v1=42;
	auto f=[&v1]{return v1;};
	v1=0;
	auto j=f();      //j=0
}

隱式捕獲

  • 使得編譯器自己推斷捕獲列表,我們可以告訴編譯器使用值捕獲還是引用捕獲:
  • [=]採用值捕獲;
  • [&]採用引用捕獲;

顯式捕獲隱式捕獲混用

  • 捕獲列表的第一個元素必須是=或者&
  • 顯式捕獲必須使用和隱式捕獲不同的方式:
  • [=, var]:var必須爲引用捕獲
  • [&,var]:var必須爲值捕獲

可變lambda

  • 值捕獲的lambda表達式中,如果想要改變該變量的值,必須加上關鍵字mutable
void fcn3(){
	int v1=42;
	auto f=[v1]() mutable {return ++v1;};
	v1=0;
	auto j=f();//j=43
}
  • 在引用捕獲中,能否改變捕獲變量的值取決於該變量是否是const:
void fcn4(){
	int v1=42;
	auto f=[&v1](){return ++v1;};
	v1=0;
	auto j=f();//j=1
}

捕獲列表的作用:

當可調用對象只能接受一個參數,但是需要兩個或者多個參數才能完成操作時,這個時候lambda表達式的參數列表只能有一個,哪另外一個參數怎麼傳進來呢?就是靠捕獲列表;

如果要使用函數來替代lambda表達式的功能,碰到這種只能傳入單一參數的情況,還有一種解決方式,使用標準庫bind函數。

bind函數 (functional頭文件)

  • 先定義一個可以傳入兩個或多個參數完成操作的函數
bool func1(int a1,int a2){
	return a1>=a2;
}
  • 然後使用bind函數將這個func1函數再封裝一層:
auto func2=bind(func1,_1,6);
  • 其中_1 _2…是佔位符,代表func2的第一個、第二個…參數,我們這裏我們將func1的第二個參數綁定爲6,這樣,func2就變成了一個只需要傳入一個參數的函數(可調用對象);func2傳入的參數類型和返回類型和func1完全一樣。
  • 使用佔位符需要使用std::placeholders命名空間:
using namespace std::placeholders;

使用bind可以重排參數順序

  • 函數g只需要傳入兩個參數,g(m,n),則mn會分別傳入_1_2的位置:
auto g=bind(f,a,b,_2,c,_1);

g(m,n)等價於f(a,b,n,c,m)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章