lambda 結(jié)構(gòu)
[capture_block](parameters) mutable exception_specification->return_type{ body }
- catpure block: 指定如何捕捉所在作用域中的變量窿侈,并供給lambda主體使用
- parameter: 可選, lambda表達式使用的參數(shù)列表。
- mutable: 可選, 如果所在作用域的變量是通過值捕捉到淤井,那么lambda表達式主體中可以使用這些變量的副本。這些副本默認(rèn)標(biāo)記為const,因此lambda表達式的主體不能修改這些副本的值币狠。如果lambda表達式標(biāo)記為mutable游两,那么這些副本則不是const,因此主體可以修改這些本地副本漩绵。
- exception_specification:(可選)用于指定lambda可以拋出的異常贱案。
- return_type:(可選)返回值的類型。如果忽略了return_type止吐,那么編譯器會根據(jù)以下原則判斷返回類型:
如果lambda表達式主體的形式為{return expression;}
那么表達式return_type的類型為expression的類型宝踪。
其他情況下的return_type為void
Hello lambda
// 注意 尾部 () 表示立馬執(zhí)行
std::string str = []{ return "Hello lambda"; }();
std::cout<< str << std::endl;
auto fn = [](const std::string &str){ return "Hello " + str; };
std::cout << fn("fn1") << std::endl;
std::cout << fn("fn2") << std::endl;
捕捉塊
lambda表達式的方括號部分稱為lambda捕捉塊(capture block),在這里可以指定如何從所在作用域中捕捉變量碍扔。捕捉變量的意思是可以在lambda表達式主體中使用這個變量瘩燥。有兩種方式:
[=]:通過值捕捉所有變量
[&]:通過引用捕捉所有變量
指定空白的捕捉塊[]表示不從所在作用域中捕捉變量。還可以酌情決定捕捉那些變量以及這些變量的捕捉方法不同,方法是指定一個捕捉列表厉膀,其中帶有可選的默認(rèn)捕捉選項。前綴為&的變量通過引用捕捉二拐。不帶前綴的變量通過值捕捉服鹅。默認(rèn)捕捉應(yīng)該是捕捉列表中的第一個元素,可以是=或&百新。
例如:
[&x]只通過引用捕捉x企软,不捕捉其他變量。
[x]只通過值捕捉x吟孙,不捕捉其他變量澜倦。
[=, &x, &y]默認(rèn)通過值捕捉杰妓,變量x和y例外藻治,這兩個變量通過引用捕捉。
[&, x]默認(rèn)通過引用捕捉巷挥,變量x例外桩卵,這個變量通過引用捕捉。
[&x, &y]非法倍宾,因為標(biāo)志符不允許重復(fù)雏节。
通過引用捕捉變量的時候,一定保證黨lambda表達式在執(zhí)行的時候高职,這個引用還是可用的
// 通過值來捕捉
std::function<int(void)> mutiplyBy2Lambda(int x)
{
return [=](){ return x * 2; };
}
// 通過引用來捕捉
std::function<int(void)> mutiplyBy3Lambda(int x)
{
// 當(dāng)函數(shù)結(jié)束的時候 x 的內(nèi)存就會被釋放, 因此這樣的做法是有問題
return [&](){ return x * 2; };
}
int main(int argc, const char * argv[])
{
// 打印結(jié)果: 4
auto fn = mutiplyBy2Lambda(2);
std::cout << fn() << std::endl;
// 打印結(jié)果: 隨機值
auto fn3 = mutiplyBy3Lambda(2);
std::cout << fn3() << std::endl;
int i = 2;
// 打印結(jié)果: 9
auto tFn3 = [&]{ return 3 * i; };
// 打印結(jié)果: 4
auto tFn = [=] { return 2 * i; };
i++;
std::cout << "i = " << i << std::endl;
std::cout << "tFn3() = " << tFn3() << std::endl;
std::cout << "tFn() = " << tFn() << std::endl;
return 0;
}
轉(zhuǎn)自: http://blog.csdn.net/xuexiacm/article/details/39835085