lamda表示式是c++11中引入的一項新技術,利用lamda表示式可以編寫內嵌的匿名函式,用以替換獨立函式或者函式物件,並且使得**更可讀。是一種匿名函式,即沒有函式名的函式;lamda函式的語法定義如下:
[capture] :捕捉列表,捕捉列表總是作為lambda的開始,即出現於lambda的開始處。它是lambda的引出符(即開始標誌)。編譯器可以根據該「標誌」來作出判斷出該函式是否為lambda函式。同時「捕捉列表」能夠捕捉上下文中的變數以作為lambda函式使用。
(parameters):引數列表。和c/c++中的普通函式引數意義一樣。該部分是可選的,意味著如果我們不需要進行引數傳遞時,可以連同括號「()」一起省略掉。
mutable:該關鍵字為乙個修飾符。在預設的情況下,lambda函式總是返回乙個const,而當我們在引數列表後面註明了「mutable」關鍵字之後,則可以取消其常量性質。若在lambda中使用了mutable修飾符,則「引數列表」是不可省略掉的(即使是引數為空)。
->return-type: 函式的返回值型別。和c/c++中的普通函式返回值型別的性質一樣。主要目的是用來追蹤lambda函式(有返回值情況下)的返回型別。若lambda函式不需要返回值,則可以直接將這部分省略掉。
:函式體。在該函式體中,除了可以使用引數列表中的變數外,還可以使用所有捕獲到的變數(即[capture] 中的變數)。
【示例】
// 指明返回型別
auto add = (int a, int b) -> int ;
// 自動推斷返回型別
auto multiply = (int a, int b) ;
int sum = add(2, 5); // 輸出:7
int product = multiply(2, 5); // 輸出:10
c++11中的lambda函式,其中的「捕捉列表」是由0個或多個「捕捉項」組成,並以逗號「,」分隔。捕捉列表有如下幾種形式:
(1)預設不捕獲任何變數;
(2)[var]表示值傳遞方式捕捉變數var;
(3)[=]表示值傳遞方式捕捉所有***域的變數(包括this);
(4)[&var]表示引用傳遞捕捉所有變數var;
(5)[&] 表示引用傳遞捕捉所有父作用域的比**(包括this);
(6)[=, &x]表示以值捕獲所有變數,當x例外,通過引用捕獲;
(7)[&, x]表示以引用捕獲所有變數,但x例外,通過值捕獲;
(8)[this] 表示引用捕獲當前物件(其實是複製指標);
(9)[*this]表示通過值方式捕獲當前物件;
【示例1】
#include #include #include using namespace std;
int main()
; printf("sum[%d]\n",retval());
printf("a[%d] b[%d] c[%d]\n",a,b,c);
return 0;
}
執行結果:
inner c[3]
inner c2[30]
sum[30]
a[10] b[20] c[3]
【示例2】
#include #include #include using namespace std;
int main()
; printf("sum[%d]\n",retval());
printf("a[%d] b[%d] c[%d]\n",a,b,c);
return 0;
}
執行結果:
inner a[1] b[2] c[3]
sum[30]
a[10] b[20] c[30]
關於c++11中lamda表示式更詳盡的內容參見:
在c++11之前,類模板和函式模板只能含有固定數量的模板引數。c++11增強了模板功能,允許模板定義中包含0到任意個模板引數,這就是可變引數模板。
可變引數模板和普通模板的語義是一樣的,只是寫法上稍有區別,宣告可變引數模板時需要在typename或class後面帶上省略號「…」:
templatevoid func(t ... args)//t叫模板引數包,args叫函式引數包
func(); // ok:args不含有任何實參
func(1); // ok:args含有乙個實參:int
func(2, 1.0); // ok:args含有兩個實參int和double
定義乙個可變引數模板函式的定義如下:
#include using namespace std;
templatevoid func(t ... args)
int main()
執行結果:
num = 0
num = 1
num = 2
引數包的展開(1)遞迴方式展開
通過遞迴函式展開引數包,需要提供乙個引數包展開的函式和乙個遞迴終止函式。
#include using namespace std;
//遞迴終止函式
void debug()
//展開函式
template void debug(t first, args ... last)
int main()
執行結果:
parameter 1
parameter 2
parameter 3
parameter 4
empty
(2)非遞迴方式展開
#include using namespace std;
template void print(t arg)
template void expand(args ... args)
; }
int main()
執行結果:
123
4
【示例】通過可變引數模板實現列印函式
#include #include using namespace std;
void debug(const char* s)
cout << *s++;
} } templatevoid debug(const char* s, t value, args... args)
cout << *s++;
} throw runtime_error("extra arguments provided to debug");
} int main()
執行結果:
(1)繼承方式展開引數包
可變引數模板類的展開一般需要定義2 ~ 3個類,包含類宣告和特化的模板類:
#include #include using namespace std;
templateclass bmw{}; // 變長模板的宣告
template// 遞迴的偏特化定義
class bmw: public bmw
head head;
}; template<> class bmw<>{}; // 邊界條件
int main()
執行結果:
type:f
type:c
tepy:i
(2)模板遞迴和特化方式展開引數包
#include using namespace std;
template struct multiply;// 變長模板的宣告
template struct multiply// 變長模板類
; template<> struct multiply<> // 邊界條件
; int main()
執行結果:
120
C 委託 Lamda表示式
1 using system 2using system.collections.generic 3using system.linq 4using system.text 5using system.threading.tasks 67 namespace816 17static void mai...
C 中委託,匿名函式,lamda表示式複習
一 委託 1.就給模擬較,類用class宣告,委託用delegate宣告。2.委託要指向乙個真正的方法。3.委託的簽名,要和指向的方法一樣。1.宣告乙個委託 public delegate void delsayhi string name public static void sayhichine...
LAMDA表示式學習
1.普通繫結 public void button1 click object sender,eventargs e this.button1.click button1 click 2.匿名委託 this.button1.click delegate object sender,eventargs...