C++ åèæå
- C++11
- C++14
- C++17
- C++20
- C++ ç¼è¯å¨æ¯ææ åµè¡¨
- ç¬ç«ä¸å®¿ä¸»å®ç°
- C++ è¯è¨
- å鿍¡æ¿(C++14 èµ·)
- æ´æ°åé¢é
- èååå§å
- æ¯è¾è¿ç®ç¬¦
- é»è®¤æ¯è¾(C++20 èµ·)
- 转ä¹åºå
- for 循ç¯
- while 循ç¯
- ç¨æ·å®ä¹è½¬æ¢
- SFINAE
- 䏻彿°
- ASCII ç 表
- æ è¯ç¬¦
- ç±»å
- å 忍¡å
- 对象
- åºæ¬æ¦å¿µ
- 表达å¼
- 声æ
- åå§å
- 彿°
- è¯å¥
- ç±»
- è¿ç®ç¬¦éè½½
- 模æ¿
- å¼å¸¸
- äºå¡æ§å å
- å ä½ç¬¦ç±»å说æç¬¦ (C++11 èµ·)
- decltype 说æç¬¦
- 彿°å£°æ
- final 说æç¬¦ (C++11 èµ·)
- override 说æç¬¦(C++11 èµ·)
- å¼ç¨å£°æ
- ç§»å¨æé 彿°
- ç§»å¨èµå¼è¿ç®ç¬¦
- æä¸¾å£°æ
- constexpr 说æç¬¦(C++11 èµ·)
- å表åå§å (C++11 èµ·)
- æé 彿°ä¸æååå§åå¨å表
- using 声æ
- nullptrï¼æéåé¢é
- åºç¡ç±»å
- ç±»åå«åï¼å«å模ç (C++11 èµ·)
- å½¢åå
- èåä½å£°æ
- å符串åé¢é
- ç¨æ·å®ä¹åé¢é (C++11 èµ·)
- 屿§è¯´æç¬¦åºå(C++11 èµ·)
- Lambda è¡¨è¾¾å¼ (C++11 èµ·)
- noexcept 说æç¬¦ (C++11 èµ·)
- noexcept è¿ç®ç¬¦ (C++11 èµ·)
- alignof è¿ç®ç¬¦(C++11 èµ·)
- alignas 说æç¬¦ (C++11 èµ·)
- åå¨ç±»è¯´æç¬¦
- åºäºèå´ç for å¾ªç¯ (C++11 èµ·)
- static_assert 声æ
- éå¼è½¬æ¢
- 代ç¨è¿ç®ç¬¦è¡¨ç¤º
- èªå¢/èªåè¿ç®ç¬¦
- æå 表达å¼(C++17 èµ·)
- 类模æ¿å®åæ¨å¯¼(C++17 èµ·)
- 模æ¿å½¢å䏿¨¡æ¿å®å
- if è¯å¥
- inline 说æç¬¦
- ç»æåç»å®å£°æ (C++17 èµ·)
- switch è¯å¥
- å符åé¢é
- å½å空é´
- æ±å¼é¡ºåº
- å¤å¶æ¶é¤
- consteval 说æç¬¦ (C++20 èµ·)
- constinit 说æç¬¦ (C++20 èµ·)
- åç¨ (C++20)
- 模å (C++20 èµ·)
- 约æä¸æ¦å¿µ (C++20 èµ·)
- new 表达å¼
- do-while 循ç¯
- continue è¯å¥
- break è¯å¥
- goto è¯å¥
- return è¯å¥
- 卿å¼å¸¸è¯´æ
- throw 表达å¼
- try å
- å½å空é´å«å
- 类声æ
- cvï¼const ä¸ volatileï¼ç±»åéå®ç¬¦
- é»è®¤åå§å
- å¼åå§å(C++03 èµ·)
- é¶åå§å
- å¤å¶åå§å
- ç´æ¥åå§å
- 常éåå§å
- å¼ç¨åå§å
- å¼ç±»å«
- C++ è¿ç®ç¬¦ä¼å 级
- å¸å°åé¢é
- æµ®ç¹åé¢é
- typedef 说æç¬¦
- æ¾å¼ç±»å转æ¢
- static_cast 转æ¢
- dynamic_cast 转æ¢
- const_cast 转æ¢
- reinterpret_cast 转æ¢
- delete 表达å¼
- æé 彿°ä¸æååå§åå¨å表
- this æé
- 访é®è¯´æç¬¦
- åå 声æ
- virtual 彿°è¯´æç¬¦
- explicit 说æç¬¦
- éææå
- é»è®¤æé 彿°
- å¤å¶æé 彿°
- å¤å¶èµå¼è¿ç®ç¬¦
- ææå½æ°
- 类模æ¿
- 彿°æ¨¡æ¿
- æ¾å¼ï¼å ¨ï¼æ¨¡æ¿ç¹å
- æ±ç¼å£°æ
- C++ çåå²
- ä½ç¨å
- çåæ
- å®ä¹ä¸åä¸å®ä¹è§åï¼ODRï¼
- å忥æ¾
- æéå®çå忥æ¾
- æ éå®çå忥æ¾
- å¦åè§å
- æªå®ä¹è¡ä¸º
- ç¿»è¯é¶æ®µ
- 常é表达å¼
- èµå¼è¿ç®ç¬¦
- ç®æ¯è¿ç®ç¬¦
- é»è¾è¿ç®ç¬¦
- æå访é®è¿ç®ç¬¦
- å ¶ä»è¿ç®ç¬¦
- sizeof è¿ç®ç¬¦
- typeid è¿ç®ç¬¦
- æé声æ
- æ°ç»å£°æ
- è¯è¨é¾æ¥
- 详述类å说æç¬¦
- é»è®¤å®å
- åé¿å®å
- å®åä¾èµæ¥æ¾
- éè½½å³è®®
- éè½½å½æ°çå°å
- æ³¨å ¥ç±»å
- ééææ°æ®æå
- ééææå彿°
- åµå¥ç±»
- æ´¾çç±»
- 空åºç±»ä¼å
- æ½è±¡ç±»
- ä½å
- è½¬æ¢æé 彿°
- æå模æ¿
- 模æ¿å®åæ¨å¯¼
- é¨å模æ¿ç¹å
- sizeof... è¿ç®ç¬¦
- å¾ å³å
- 彿° try å
- æ©å å½åç©ºé´ std
- åæ¯ç¼©å
- RAII
- ä¸/äº/é¶ä¹æ³å
- PImpl
- é¶å¼éåå
- ç±»å
- éå¼è½¬æ¢
- 注é
- C++ å ³é®è¯
- é¢å¤çå¨
- C++ æ ååºå¤´æä»¶
- å ·åè¦æ±
- åè½ç¹æ§æµè¯ (C++20)
- å·¥å ·åº
- ç±»åæ¯æï¼åºæ¬ç±»åãRTTIãç±»åç¹æ§ï¼
- æ¦å¿µåº (C++20)
- é误å¤ç
- 卿å å管ç
- æ¥æåæ¶é´å·¥å ·
- å符串åº
- 容å¨åº
- è¿ä»£å¨åº
- èå´åº (C++20)
- ç®æ³åº
- æ°å¼åº
- è¾å ¥/è¾åºåº
- æä»¶ç³»ç»åº
- æ¬å°ååº
- æ£å表达å¼åº
- ååæä½åº
- çº¿ç¨æ¯æåº
- å®éªæ§ C++ ç¹æ§
- æç¨çèµæº
- ç´¢å¼
- std 符å·ç´¢å¼
- åç¨æ¯æ (C++20)
- C++ å ³é®è¯
ä½ç½®ï¼é¦é¡µ > C++ åèæå >C++ è¯è¨ > Lambda è¡¨è¾¾å¼ (C++11 èµ·)
Lambda è¡¨è¾¾å¼ (C++11 èµ·)
æé éå ï¼è½å¤æè·ä½ç¨åä¸çåéçæ å彿°å¯¹è±¡ã
è¯æ³
[ æè· ] <模æ¿å½¢å>(å¯é)(C++20) ( å½¢å ) 说æç¬¦(å¯é) å¼å¸¸è¯´æ attr -> ret requires(å¯é)(C++20) { 彿°ä½ }
|
(1) | ||||||||
[ æè· ] ( å½¢å ) -> ret { 彿°ä½ }
|
(2) | ||||||||
[ æè· ] ( å½¢å ) { 彿°ä½ }
|
(3) | ||||||||
[ æè· ] { 彿°ä½ }
|
(4) | ||||||||
1) 宿´å£°æã
2) const lambda ç声æï¼å¤å¶æè·çå¯¹è±¡å¨ lambda ä½å 为 constã
3) çç¥å°¾éè¿åç±»åï¼éå
ç operator() çè¿åç±»åä» return è¯å¥æ¨å¯¼ï¼å¦å对äºå£°æè¿åç±»å为 auto ç彿°çæ¨å¯¼ä¸æ ·ã
4) çç¥å½¢åå表ï¼ä¸æ¥æ¶å®åç彿°ï¼å¦åå½¢ååè¡¨æ¯ ()ãä»
å½ constexprãmutableãå¼å¸¸è¯´æã屿§æå°¾éè¿åç±»åå
¨é½ä¸ä½¿ç¨æ¶æè½ä½¿ç¨æ¤å½¢å¼ã
è§£é
| æè· | - | é¶ææ´å¤æè·ç¬¦çéå·åéå表ï¼å¯éå°ä»¥ é»è®¤æè·ç¬¦ï¼capture-defaultï¼ èµ·å§ã
æå ³æè·ç¬¦çè¯¦ç»æè¿°ï¼è§ä¸æã è¥åéæ»¡è¶³ä¸åæ¡ä»¶ï¼å lambda 表达å¼å¯ä»¥ä¸æè·å°±ä½¿ç¨å®
è¥åéæ»¡è¶³ä¸åæ¡ä»¶ï¼å lambda 表达å¼å¯ä»¥ä¸æè·å°±è¯»åå ¶å¼
| ||||
| <模æ¿å½¢å>(C++20) | - | ï¼è§æ¬å·ä¸çï¼æ¨¡æ¿å½¢åå表ï¼ç¨äºä¸ºæ³å lambda æä¾å模æ¿å½¢åçååï¼è§ä¸æç ClosureType::operator()ï¼ãä¸å¨æ¨¡æ¿å£°æä¸ç¸ä¼¼ï¼æ¨¡æ¿å½¢åå表å¯ä»¥åéå¯éç requires åå¥ï¼å®æå®å模æ¿å®åä¸çå¶çº¦ãè¥æä¾ï¼å模æ¿å½¢åå表ä¸è½ä¸ºç©ºï¼ä¸å
许 <>ï¼ã
| ||||
| å½¢å | - | å½¢åå表ï¼å¦å¨å
·å彿°ä¸ï¼ä½ä¸å
许é»è®¤å®å (C++14 å)ãå½ä»¥ auto 为形åç±»åæ¶ï¼è¯¥ lambda 为æ³å lambdaã (C++14 èµ·)
| ||||
| 说æç¬¦ | - | å¯éç说æç¬¦çåºåãå
许ä¸å说æç¬¦ï¼
| ||||
| å¼å¸¸è¯´æ | - | 为éå
ç±»åç operator() æä¾å¼å¸¸è¯´ææ noexcept åå¥
| ||||
| attr | - | 为éå
ç±»åç彿°è°ç¨è¿ç®ç¬¦çç±»åæä¾å±æ§è¯´æãè¿æ ·æå®çä»»ä½å±æ§åå±äºå½æ°è°ç¨è¿ç®ç¬¦çç±»åï¼èé彿°è°ç¨è¿ç®ç¬¦èªèº«ãï¼ä¾å¦ä¸è½ä½¿ç¨ [[noreturn]]
| ||||
| ret | - | è¿åç±»åãè¥ç¼ºå¤±ï¼åç±å½æ°ç return è¯å¥æè´å«ï¼æå½å½æ°ä¸è¿åä»»ä½å¼æ¶ä¸º voidï¼ | ||||
| requires | - | åéå ç±»åç operator() æ·»å å¶çº¦ | ||||
| 彿°ä½ | - | 彿°ä½ |
Lambda è¡¨è¾¾å¼æ¯çº¯å³å¼è¡¨è¾¾å¼ï¼å ¶ç±»åæ¯ç¬æçæ åéèåéèå类类åï¼è¢«ç§°ä¸ºéå ç±»åï¼closure typeï¼ï¼å®ï¼å¯¹äº ADL èè¨ï¼å£°æäºå«æè¯¥ lambda 表达å¼çæå°åä½ç¨åãç±»ä½ç¨åæå½å空é´ä½ç¨åãéå ç±»åæä¸åæåï¼
ClosureType::operator()(å½¢å)
| ret operator()(å½¢å) const { 彿°ä½ } |
(æªä½¿ç¨å ³é®è¯ mutable) | |
| ret operator()(å½¢å) { 彿°ä½ } |
(使ç¨äºå ³é®è¯ mutable) | |
| template<模æ¿å½¢å> ret operator()(å½¢å) const { 彿°ä½ } |
(C++14 èµ·) (æ³å lambda) |
|
| template<模æ¿å½¢å> ret operator()(å½¢å) { 彿°ä½ } |
(C++14 èµ·) (æ³å lambdaï¼ä½¿ç¨äºå ³é®è¯ mutable) |
|
å½è¢«è°ç¨æ¶ï¼æ§è¡ lambda 表达å¼ç彿°ä½ãå½è®¿é®åéæ¶ï¼è®¿é®çæ¯å ¶è¢«æè·ç坿¬ï¼å¯¹äºä»¥å¤å¶æè·çå®ä½ï¼æå对象ï¼å¯¹äºä»¥å¼ç¨æè·çå®ä½ï¼ãé¤é lambda 表达å¼ä¸ä½¿ç¨äºå ³é®è¯ mutableï¼å¦å彿°è°ç¨è¡¨è¾¾å¼è¢« const éå®ï¼ä¸ä»¥å¤å¶æè·ç对象ä»è¿ä¸ª operator() çå é¨ä¸å¯ä¿®æ¹ã彿°è°ç¨è¿ç®ç¬¦å§ç»ä¸è¢« volatile éå®ä¸å§ç»éèã
|
è¥å½æ°è°ç¨è¿ç®ç¬¦æ»¡è¶³é对 constexpr 彿°çè¦æ±ï¼åå®å§ç»æ¯ constexprãè¥å
³é®è¯ |
(C++17 èµ·) |
|
è¥å¨ lambda 表达å¼ä¸ä½¿ç¨å
³é®è¯ |
(C++20 èµ·) |
|
å¯¹äº å½¢å 䏿¯ä¸ªç±»åæå®ä¸º // æ³å lambdaï¼operator() æ¯æä¸¤ä¸ªå½¢åçæ¨¡æ¿ auto glambda = [](auto a, auto&& b) { return a < b; }; bool b = glambda(3, 3.14); // ok  // æ³å lambdaï¼operator() æ¯æä¸ä¸ªå½¢åçæ¨¡æ¿ auto vglambda = [](auto printer) { return [=](auto&&... ts) // æ³å lambdaï¼ts æ¯å½¢åå { printer(std::forward<decltype(ts)>(ts)...); return [=] { printer(ts...); }; // é¶å lambda ï¼ä¸æ¥åå½¢åï¼ }; }; auto p = vglambda([](auto v1, auto v2, auto v3) { std::cout << v1 << v2 << v3; }); auto q = p(1, 'a', 3.14); // è¾åº 1a3.14 q(); // è¾åº 1a3.14
|
(C++14 èµ·) |
|
è¥ lambda å®ä¹ä½¿ç¨æ¾å¼ç模æ¿å½¢åå表ï¼å该模æ¿å½¢åå表ç¨äº // æ³å lambdaï¼operator() æ¯æä¸¤ä¸ªå½¢åçæ¨¡æ¿ auto glambda = []<class T>(T a, auto&& b) { return a < b; };  // æ³å lambdaï¼operator() æ¯æä¸ä¸ªå½¢åå çæ¨¡æ¿ auto f = []<typename ...Ts>(Ts&& ...ts) { return foo(std::forward<Ts>(ts)...); }; |
(C++20 èµ·) |
Lambda 表达å¼ä¸çå¼å¸¸è¯´æ å¼å¸¸è¯´æ åºç¨äºå½æ°è°ç¨è¿ç®ç¬¦æè¿ç®ç¬¦æ¨¡æ¿ã
对äºå忥æ¾ï¼ç¡®å® this æéçç±»ååå¼ï¼ä»¥å对äºè®¿é®ééæç±»æåèè¨ï¼éå ç±»åç彿°è°ç¨è¿ç®ç¬¦ç彿°ä½è¢«è®¤ä¸ºå¤äº lambda 表达å¼çè¯å¢ä¸ã
struct X { int x, y; int operator()(int); void f() { // ä¸å lambda çè¯å¢æ¯æå彿° X::f [=]()->int { return operator()(this->x + y); // X::operator()(this->x + (*this).y) // æ¥æç±»å X* }; } };
ClosureType ç operator() ä¸è½å¨åå
声æä¸æåã
æ¬åå¼ç¨
è¥ä»¥å¼ç¨é弿æ¾å¼æè·éå¼ç¨å®ä½ï¼èå¨è¯¥å®ä½ççåæç»æä¹åè°ç¨éå 对象ç彿°è°ç¨è¿ç®ç¬¦ï¼ååçæªå®ä¹è¡ä¸ºãC++ çéå å¹¶ä¸å»¶é¿è¢«æè·çå¼ç¨ççåæã
è¿åæ ·éç¨äºè¢«æè·ç this æéææåç对象ççåæã
ClosureType::operator ret(*)(å½¢å)()
| æ æè·çéæ³å lambda |
||
| using F = ret(*)(å½¢å); operator F() const; |
(C++17 å) | |
| using F = ret(*)(å½¢å); constexpr operator F() const; |
(C++17 èµ·) | |
| æ æè·çæ³å lambda |
||
| template<模æ¿å½¢å> using fptr_t = /*è§ä¸æ*/; template<模æ¿å½¢å> operator fptr_t<模æ¿å½¢å>() const; |
(C++14 èµ·) (C++17 å) |
|
| template<模æ¿å½¢å> using fptr_t = /*è§ä¸æ*/; template<模æ¿å½¢å> constexpr operator fptr_t<模æ¿å½¢å>() const; |
(C++17 èµ·) | |
ä» å½ lambda 表达å¼çæè·ç¬¦åè¡¨ä¸ºç©ºæ¶æå®ä¹è¿ä¸ªç¨æ·å®ä¹è½¬æ¢å½æ°ã宿¯éå 对象çå ¬å¼ãconstexprã (C++17 èµ·)éèãé explicitãconst noexcept (C++14 èµ·) æå彿°ãè¥ lambda ç彿°è°ç¨è¿ç®ç¬¦æ¯ç«å³å½æ°ï¼å转æ¢å½æ°äº¦ä¸ºç«å³å½æ°ã (C++20 èµ·)
|
æ³åæ æè· lambda æ¥æä¸ä¸ªç¨æ·å®ä¹ç转æ¢å½æ°æ¨¡æ¿ï¼å®å ·æä¸å½æ°è°ç¨è¿ç®ç¬¦æ¨¡æ¿ç¸åçè设模æ¿å½¢åå表ãè¥å ¶è¿åç±»å为空æ autoï¼åç±å½æ°æ¨¡æ¿ç¹åä¸çè¿åç±»åæ¨å¯¼è·å¾ï¼èå®å以转æ¢å½æ°æ¨¡æ¿ç模æ¿å®åæ¨å¯¼è·å¾ã void f1(int (*)(int)) {} void f2(char (*)(int)) {} void h(int (*)(int)) {} // #1 void h(char (*)(int)) {} // #2 auto glambda = [](auto a) { return a; }; f1(glambda); // ok f2(glambda); // é误ï¼ä¸å¯è½¬æ¢ h(glambda); // okï¼è°ç¨ #1ï¼å 为 #2 ä¸å¯è½¬æ¢  int& (*fpi)(int*) = [](auto* a)->auto& { return *a; }; // ok |
(C++14 èµ·) |
è¿ä¸ªè½¬æ¢å½æ°æè¿åçå¼ï¼æ¯æåä¸ä¸ªå ·æ C++ è¯è¨è¿æ¥ç彿°ï¼èè°ç¨è¯¥å½æ°æ¶ï¼ææä¸ç´æ¥è°ç¨éå 对象ç彿°è°ç¨è¿ç®ç¬¦ç¸åã
|
è¥å½æ°è°ç¨è¿ç®ç¬¦ï¼æå¯¹äºæ³å lambda ä¸ºå ¶ç¹åï¼ä¸º constexprï¼åæ¤å½æ°ä¸º constexprã auto Fwd= [](int(*fp)(int), auto a){return fp(a);}; auto C=[](auto a){return a;}; static_assert(Fwd(C,3)==3);// OK auto NC=[](auto a){ static int s; return a;}; static_assert(Fwd(NC,3)==3); // é误ï¼å 为 static s èä¸è½ä¸º constexpr çç¹å è¥éå
对象ç |
(C++17 èµ·) |
|
è¥å½æ°è°ç¨è¿ç®ç¬¦ï¼æå¯¹äºæ³å lambda ä¸ºå ¶ç¹åï¼æ¯ç«å³å½æ°ï¼åæ¤å½æ°æ¯ç«å³å½æ°ã |
(C++20 èµ·) |
ClosureType::ClosureType()
| ClosureType() = delete; |
(C++14 å) | |
| ClosureType() = default; |
(C++20 èµ·)(ä» å½æªæå®ä»»ä½æè·æ¶) | |
| ClosureType(const ClosureType& ) = default; |
(C++14 èµ·) | |
| ClosureType(ClosureType&& ) = default; |
(C++14 èµ·) | |
|
éå ç±»åéå¯é»è®¤æé (DefaultConstructible) ãéå ç±»å带æè¢«å¼ç½®ç (C++14 å)没æ (C++14 èµ·)é»è®¤æé 彿°ã |
(C++20 å) |
|
è¥æªæå® æè·ï¼åéå ç±»åæ¥æé¢ç½®çé»è®¤æé 彿°ãå¦åï¼å®æ²¡æé»è®¤æé 彿°ï¼è¿å 嫿 é»è®¤æè·ç¬¦ï¼capture-defaultï¼ çæ åµï¼å³ä½¿å®é ä¸å®ä¸æè·ä»»ä½åé乿¯å¦æ¤ï¼ã |
(C++20 èµ·) |
å¤å¶æé 彿°ä¸ç§»å¨æé 彿°è¢«éå¼å£°æ (C++14 å)声æä¸ºé¢ç½®ç (C++14 èµ·)ï¼å¹¶æç §å¤å¶æé 彿°ä¸ç§»å¨æé 彿°çé常è§åéå¼å®ä¹ã
ClosureType::operator=(const ClosureType&)
| ClosureType& operator=(const ClosureType&) = delete; |
(C++20 å) | |
| ClosureType& operator=(const ClosureType&) = default; ClosureType& operator=(ClosureType&&) = default; |
(C++20 èµ·) (ä» å½æªæå®ä»»ä½æè·æ¶) |
|
| ClosureType& operator=(const ClosureType&) = delete; |
(C++20 èµ·) (å ¶ä»æ åµ) |
|
|
å¤å¶èµå¼è¿ç®ç¬¦è¢«å®ä¹ä¸ºå¼ç½®çï¼ä¸æªå£°æç§»å¨èµå¼è¿ç®ç¬¦ï¼ãéå ç±»åéå¯å¤å¶èµå¼ (CopyAssignable) ã |
(C++20 å) |
|
è¥ä¸æå® æè·ï¼åéå ç±»åæ¥æé¢ç½®çå¤å¶èµå¼è¿ç®ç¬¦åé¢ç½®çç§»å¨èµå¼è¿ç®ç¬¦ãå¦åï¼å®æ¥æå¼ç½®çå¤å¶èµå¼è¿ç®ç¬¦ï¼è¿å 嫿 é»è®¤æè·ç¬¦ çæ åµï¼å³ä½¿å®é ä¸å®ä¸æè·ä»»ä½åé乿¯å¦æ¤ï¼ã |
(C++20 èµ·) |
ClosureType::~ClosureType()
| ~ClosureType() = default; |
||
ææå½æ°æ¯éå¼å£°æçã
ClosureType::Captures
| T1 a; T2 b; |
||
è¥ lambda 表达å¼ä»¥å¤å¶ï¼éå¼å°ä»¥æè·åå¥ [=] ææ¾å¼å°ä»¥ä¸å«å符 & çæè·ç¬¦ï¼ä¾å¦ [a, b, c]ï¼æè·äºä»»ä½å
容ï¼åéå
ç±»åå
å«ä¿æææè¢«å¦æ¤æè·çå®ä½ç坿¬çæ åééææ°æ®æåï¼å®ä»¬ä»¥æªææç顺åºå£°æã
对åºäºæ åå§åå¨çæè·ç¬¦çæ°æ®æåï¼å¨æ±å¼ lambda è¡¨è¾¾å¼æ¶è¢«ç´æ¥åå§åã对åºäºå¸¦æåå§åå¨çæè·ç¬¦çï¼åæå ¶åå§åå¨çè¦æ±åå§åï¼å¯ä¸ºå¤å¶æç´æ¥åå§åï¼ãè¥æè·äºæ°ç»ï¼ååæ°ç»å ç´ ä»¥ä¸æ éå¢é¡ºåºç´æ¥åå§åãåå§ååæ°æ®æåæç¨çé¡ºåºæ¯å®ä»¬ç声æé¡ºåºï¼å®æ¯æªææçï¼ã
æ¯ä¸ªæ°æ®æåçç±»åæ¯å ¶å¯¹åºè¢«æè·å®ä½çç±»åï¼é¤éå®ä½æ¥æå¼ç¨ç±»åï¼è¯¥æ åµä¸ï¼å°å½æ°çå¼ç¨è¢«æè·ä¸ºå°è¢«å¼ç¨å½æ°çå·¦å¼å¼ç¨ï¼èå°å¯¹è±¡çå¼ç¨è¢«æè·ä¸ºè¢«å¼ç¨å¯¹è±¡ç坿¬ï¼ã
对äºä»¥å¼ç¨æè·ï¼ä»¥é»è®¤æè·ç¬¦ [&] æä½¿ç¨äºå符 &ï¼ä¾å¦ [&a, &b, &c]ï¼çå®ä½ï¼éå
ç±»å䏿¯å¦å£°æé¢å¤çæ°æ®æåæ¯æªææçï¼ä½ä»»ä½è¿ç§éå æåå¿
须满足åé¢ç±»å (LiteralType) (C++17 èµ·)ã
|
ä¸å 许å¨ä¸æ±å¼è¡¨è¾¾å¼ã模æ¿å®åãå«å声æãtypedef 声æï¼ä»¥å彿°ï¼æå½æ°æ¨¡æ¿ï¼å£°æä¸é¤äºå½æ°ä½å彿°çé»è®¤å®å以å¤çä»»ä½ä½ç½®ä¸åºç° lambda 表达å¼ã |
(C++20 å) |
Lambda æè·
æè· æ¯é¶ææ´å¤æè·ç¬¦çéå·åéå表ï¼å¯éå°ä»¥ é»è®¤æè·ç¬¦ å¼å§ãä» æçé»è®¤æè·ç¬¦æ¯
-
&ï¼ä»¥å¼ç¨é弿è·è¢«ä½¿ç¨çèªå¨åéï¼å -
=ï¼ä»¥å¤å¶é弿è·è¢«ä½¿ç¨çèªå¨åéï¼ã
å½åºç°ä»»ä¸é»è®¤æè·ç¬¦æ¶ï¼é½è½é弿è·å½å对象ï¼*thisï¼ãå½å®è¢«éå¼æè·æ¶ï¼å§ç»è¢«ä»¥å¼ç¨æè·ï¼å³ä½¿é»è®¤æè·ç¬¦æ¯ = 乿¯å¦æ¤ãå½é»è®¤æè·ç¬¦ä¸º = æ¶ï¼*this çé弿è·è¢«å¼ç¨ã (C++20 èµ·)
æè· ä¸åç¬çæè·ç¬¦çè¯æ³æ¯
| æ è¯ç¬¦ | (1) | ||||||||
æ è¯ç¬¦ ...
|
(2) | ||||||||
| æ è¯ç¬¦ åå§åå¨ | (3) | (C++14 èµ·) | |||||||
& æ è¯ç¬¦
|
(4) | ||||||||
& æ è¯ç¬¦ ...
|
(5) | ||||||||
& æ è¯ç¬¦ åå§åå¨
|
(6) | (C++14 èµ·) | |||||||
this
|
(7) | ||||||||
* this
|
(8) | (C++17 èµ·) | |||||||
... æ è¯ç¬¦ åå§åå¨
|
(9) | (C++20 èµ·) | |||||||
& ... æ è¯ç¬¦ åå§åå¨
|
(10) | (C++20 èµ·) | |||||||
å½é»è®¤æè·ç¬¦æ¯ & æ¶ï¼åç»§çç®åæè·ç¬¦å¿
é¡»ä¸ä»¥ & å¼å§ã
struct S2 { void f(int i); }; void S2::f(int i) { [&]{}; // OKï¼é»è®¤ä»¥å¼ç¨æè· [&, i]{}; // OKï¼ä»¥å¼ç¨æè·ï¼ä½ i ä»¥å¼æè· [&, &i] {}; // é误ï¼ä»¥å¼ç¨æè·ä¸ºé»è®¤æ¶ç以å¼ç¨æè· [&, this] {}; // OKï¼çä»·äº [&] [&, this, i]{}; // OKï¼çä»·äº [&, i] }
å½é»è®¤æè·ç¬¦æ¯ = æ¶ï¼åç»§çç®åæè·ç¬¦å¿
须以 & å¼å§ï¼æè
为 *this (C++17 èµ·) æ this (C++20 èµ·)ã
struct S2 { void f(int i); }; void S2::f(int i) { [=]{}; // OKï¼é»è®¤ä»¥å¤å¶æè· [=, &i]{}; // OKï¼ä»¥å¤å¶æè·ï¼ä½ i 以å¼ç¨æè· [=, *this]{}; // C++17 åï¼éè¯¯ï¼æ æè¯æ³ // C++17 èµ·ï¼OKï¼ä»¥å¤å¶æè·å¤å´ç S2 [=, this] {}; // C++20 åï¼é误ï¼= 为é»è®¤æ¶ç this // C++20 èµ·ï¼OKï¼å [=] }
任使è·ç¬¦åªå¯ä»¥åºç°ä¸æ¬¡ï¼
struct S2 { void f(int i); }; void S2::f(int i) { [i, i] {}; // é误ï¼i éå¤ [this, *this] {}; // é误ï¼"this" éå¤ (C++17) }
åªæå®ä¹äºåä½ç¨åæé»è®¤æååå§åå¨ä¸ç lambda 表达å¼è½æ¥æé»è®¤æè·ç¬¦ææ åå§åå¨çæè·ç¬¦ã对äºè¿ç§ lambda 表达å¼ï¼å ¶å¯è¾¾ä½ç¨åï¼reaching scopeï¼å®ä¹ä¸ºç´è³å¹¶å å«å ¶æå å±çå¤å´å½æ°ï¼åå ¶å½¢åï¼çå¤å´ä½ç¨åçéåãè¿å ¶ä¸å å«å个åµå¥çåä½ç¨åï¼ä»¥å彿¤ lambda 为åµå¥ç lambda æ¶ä¹å å«å ¶å个å¤å´ lambda çä½ç¨åã
ï¼é¤äº this æè·ç¬¦ä¹å¤çï¼ä»»ä½æ åå§åå¨çæè·ç¬¦ä¸ç æ è¯ç¬¦ï¼ä½¿ç¨éå¸¸çæ éå®å忥æ¾å¨ lambda çå¯è¾¾ä½ç¨å䏿¥æ¾ãæ¥æ¾ç»æå¿
é¡»æ¯å£°æäºå¯è¾¾ä½ç¨åä¸çï¼å
·æèªå¨å卿çåéã该åéï¼æ thisï¼è¢«æ¾å¼æè·ã
|
带æåå§åå¨çæè·ç¬¦ï¼å ¶è¡ä¸ºå¦åå®å£°æå¹¶æ¾ç¤ºæè·ä¸ä¸ªä»¥ç±»å auto 声æçåéï¼è¯¥åéç声æåºæ¯ lambda 表达å¼ä½ï¼å³å®ä¸å¨å ¶åå§åå¨çä½ç¨åä¸ï¼ï¼ä½ï¼
è¿å¯ç¨äºä»¥å¦ x = std::move(x) è¿æ ·çæè·ç¬¦æè·ä» å¯ç§»å¨çç±»åã è¿äº¦ä½¿å¾ä»¥ const å¼ç¨è¿è¡æè·ç§°ä¸ºå¯è½ï¼æ¯å¦ä»¥ &cr = std::as_const(x) æç±»ä¼¼çæ¹å¼ã int x = 4; auto y = [&r = x, x = x + 1]()->int { r += 2; return x * x; }(); // æ´æ°Â ::x 为 6 å¹¶åå§å y 为 25ã |
(C++14 èµ·) |
è¥æè·ç¬¦å表å
·æé»è®¤æè·ç¬¦ï¼ä¸æªæ¾å¼ï¼ä»¥ this æ *thisï¼æè·å
¶å¤å´å¯¹è±¡ï¼ææè·ä»»ä½èªå¨åéï¼å以䏿
åµä¸ï¼å®é弿è·ä¹
- lambda ä½ ODR å¼ä½¿ç¨äºåéæ
thisæé
void f(int, const int (&)[2] = {}) {} // #1 void f(const int&, const int (&)[1]) {} // #2 void test() { const int x = 17; auto g0 = [](auto a) { f(x); }; // okï¼è°ç¨ #1ï¼ä¸æè· x auto g1 = [=](auto a) { f(x); }; // C++14 ä¸ä¸æè· xï¼C++17 ä¸æè· x // æè·è½è¢«ä¼åæ auto g2 = [=](auto a) { int selector[sizeof(a) == 1 ? 1 : 2] = {}; f(x, selector); // okï¼æ¤ä¸ºå¾ å³è¡¨è¾¾å¼ï¼æ x 被æè· }; auto g3 = [=](auto a) { typeid(a + x); // æè· xï¼ä¸ç®¡ a + x æ¯å¦ä¸ºä¸æ±å¼æä½æ° }; } |
(C++14 èµ·) |
è¥ lambda ä½ ODR å¼ä½¿ç¨äºä»¥å¤å¶æè·çå®ä½ï¼åå®è®¿é®çæ¯éå ç±»åçæåãè¥å®æª ODR å¼ä½¿ç¨è¯¥å®ä½ï¼åè®¿é®æ¯å°å对象çï¼
void f(const int*); void g() { const int N = 10; [=]{ int arr[N]; // é ODR å¼ä½¿ç¨ï¼æä»£ g ç const int N f(&N); // ODR å¼ä½¿ç¨ï¼å¯¼è´ N 被ï¼ä»¥å¤å¶ï¼æè· // &N æ¯éå 对象çæå N çå°åï¼èé g ä¸ç N }(); }
#include <iostream>  auto make_function(int& x) { return [&]{ std::cout << x << '\n'; }; }  int main() { int i = 3; auto f = make_function(i); // f ä¸å¯¹ x ç使ç¨ç´æ¥ç»å®å° i i = 5; f(); // OKï¼æå° 5 }
å¨ lambda ä½å ï¼å¨ä»»ä½å ·æèªå¨å卿çåéä¸ä½¿ç¨çä»»ä½ decltypeï¼é½å¦åå°å®æè·å¹¶ ODR å¼ä½¿ç¨ï¼å°½ç®¡ decltype èªèº«ä¸æ¯ ODR å¼ä½¿ç¨ä¸ä¸å®é åçæè·ï¼
void f3() { float x, &r = x; [=] { // x ä¸ r ä¸è¢«æè·ï¼åºç°äº decltype çæä½æ°ä¸å¹¶ä¸æ¯ ODR å¼ä½¿ç¨ï¼ decltype(x) y1; // y1 æ¥æ float ç±»å decltype((x)) y2 = y1; // y2 æ¥æ float const& ç±»åï¼å ä¸ºæ¤ lambda // é mutable ä¸ x æ¯å·¦å¼ decltype(r) r1 = y1; // r1 æ¥æ float& ç±»åï¼ä¸èèåæ¢ï¼ decltype((r)) r2 = y2; // r2 æ¥æ float const& ç±»å }; }
Lambda æï¼é弿æ¾ç¤ºï¼æè·çä»»ä½å®ä½å被该 lambda è¡¨è¾¾å¼æ ODR å¼ä½¿ç¨ï¼å æ¤ï¼åµå¥ç lambda çé弿è·å°è§¦åå ¶å¤å´ lambda çé弿è·ï¼ã
ææé弿è·çåéå¿ é¡»å£°æäº lambda çå¯è¾¾ä½ç¨åä¸ã
è¥ lambda ï¼ä»¥ this æ *thisï¼æè·äºå
¶å¤å´å¯¹è±¡ï¼åè¦ä¹å
¶ææ¥è¿çå¤å´å½æ°å¿
é¡»æ¯ééææå彿°ï¼è¦ä¹è¯¥ lambda å¿
é¡»å¤äºæä¸ªé»è®¤æååå§åå¨ä¸ï¼
struct s2 { double ohseven = .007; auto f() { // 以ä¸ä¸¤ä¸ª lambda çææ¥è¿å¤å´å½æ° return [this] { // 以å¼ç¨æè·å¤å´ç s2 return [*this] { // 以å¤å¶æè·å¤å´ç s2 (C++17) return ohseven;â// OK } }(); } auto g() { return []{ // æ æè· return [*this]{};â// é误ï¼*this æªè¢«å¤å± lambda è¡¨è¾¾å¼ææè· }(); } };
è¥ lambda 表达å¼ï¼ææ³å lambda ç彿°è°ç¨è¿ç®ç¬¦çä¸ä¸ªå®ä¾åï¼ODR å¼ä½¿ç¨äº this æä»»ä½å
·æèªå¨å卿çåéï¼åå®å¿
须被该 lambda è¡¨è¾¾å¼ææè·ã
void f1(int i) { int const N = 20; auto m1 = [=] { int const M = 30; auto m2 = [i] { int x[N][M]; // N ä¸ M æªè¢« ODR å¼ä½¿ç¨ // ï¼å®ä»¬æªè¢«æè·æ¯ OK çï¼ x[0][0] = i; // i 被 m2 æ¾å¼æè· // 并被 m1 éå¼æè· }; };  struct s1 // f1() ä¸çå±é¨ç±» { int f; void work(int n) // ééææå彿° { int m = n * n; int j = 40; auto m3 = [this, m] { auto m4 = [&, j] { // é误ï¼j æªè¢« m3 ææè· int x = n; // é误ï¼n 被 m4 éå¼æè· // 使ªè¢« m3 ææè· x += m; // okï¼m 被 m4 æè· // ä¸ä¸º m3 æ¾å¼æè· x += i; // é误ï¼i å¨å¯è¾¾ä½ç¨åä¹å¤ // ï¼è¯¥ä½ç¨åç»äº work()ï¼ x += f; // okï¼this 被 m4 éå¼æè· // ä¸è¢« m3 æ¾å¼æè· }; }; } }; }
以ä¸å¸¦æåå§åå¨çæè·ç¬¦ä¸è½æè·ç±»æåï¼å¦ä¸æåï¼æè·ç¬¦å表ä¸ä» 容许åéï¼ï¼
class S { int x = 0; void f() { int i = 0; // auto l1 = [i, x]{ use(i, x); }; // é误ï¼x éåé auto l2 = [i, x=x]{ use(i, x); }; // OKï¼å¤å¶æè· i = 1; x = 1; l2(); // è°ç¨ use(0,0) auto l3 = [i, &x=x]{ use(i, x); }; // OKï¼å¼ç¨æè· i = 2; x = 2; l3(); // è°ç¨ use(1,2) } };
å½ lambda ç¨éå¼ç以å¤å¶æè·æè·æä¸ªæåæ¶ï¼å®å¹¶ä¸äº§ç该æååéç坿¬ï¼å¯¹æååé m ç使ç¨è¢«å¤çæè¡¨è¾¾å¼ (*this).mï¼è *this å§ç»è¢«éå¼ä»¥å¼ç¨æè·ï¼
class S { int x = 0; void f() { int i = 0; auto l1 = [=]{ use(i, x); }; // æè· i ç坿¬å this æéç坿¬ i = 1; x = 1; l1(); // è°ç¨ use(0,1)ï¼å¦å i 以å¤å¶è x 以å¼ç¨æè· auto l2 = [i, this]{ use(i, x); }; // åä¸ï¼ä»¤ä¹ä¸ºæ¾å¼æè· i = 2; x = 2; l2(); // è°ç¨ use(1,2)ï¼å¦å i 以å¤å¶è x 以å¼ç¨æè· auto l3 = [&]{ use(i, x); }; // 以å¼ç¨æè· iï¼å¹¶æè· this æéç坿¬ i = 3; x = 2; l3(); // è°ç¨ use(3,2)ï¼å¦å i ä¸ x å以å¼ç¨æè· auto l4 = [i, *this]{ use(i, x); }; // å¶é *this ç坿¬ï¼å å« x ç坿¬ i = 4; x = 4; l4(); // è°ç¨ use(3,2)ï¼å¦å i ä¸ x å以å¤å¶æè· } };
è¥ lambda 表达å¼åºç°äºé»è®¤å®åä¸ï¼åå®ä¸è½æ¾å¼æé弿è·ä»»ä½åéã
ä¸è½æè·å¿åèåä½çæåã
è¥åµå¥ç lambda m2 æè·äºä¹è¢«å
¶ç´æ¥å¤å´ lambda m1 ææè·çå®ä½ï¼å以å¦ä¸æ¹å¼å° m2 çæè·è¿è¡åæ¢ï¼
- è¥å¤å´ lambda
m1以å¤å¶æè·ï¼åm2æè·m1çéå ç±»åçééææåï¼èéååéæthisã - è¥å¤å´ lambda
m1以å¼ç¨æè·ï¼åm2æè·ååéæthisã
#include <iostream>  int main() { int a = 1, b = 1, c = 1;  auto m1 = [a, &b, &c]() mutable { auto m2 = [a, b, &c]() mutable { std::cout << a << b << c << '\n'; a = 4; b = 4; c = 4; }; a = 3; b = 3; c = 3; m2(); };  a = 2; b = 2; c = 2;  m1(); // è°ç¨ m2() å¹¶æå° 123 std::cout << a << b << c << '\n'; // æå° 234 }
示ä¾
æ¤ç¤ºä¾æ¼ç¤ºå¦ä½ä¼ é lambda ç»æ³åç®æ³ï¼ä»¥å lambda è¡¨è¾¾å¼æäº§çç对象è½å¦ä½åå¨äº std::function 对象ã
#include <vector> #include <iostream> #include <algorithm> #include <functional>  int main() { std::vector<int> c = {1, 2, 3, 4, 5, 6, 7}; int x = 5; c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; }), c.end());  std::cout << "c: "; std::for_each(c.begin(), c.end(), [](int i){ std::cout << i << ' '; }); std::cout << '\n';  // éå çç±»åä¸è½è¢«æåï¼ä½å¯ç¨ auto æå // C++14 èµ·ï¼lambda è½æ¥æèªèº«çé»è®¤å®å auto func1 = [](int i = 6) { return i + 4; }; std::cout << "func1: " << func1() << '\n';  // 䏿æå¯è°ç¨å¯¹è±¡ç¸åï¼éå è½å¯ä»¥è¢«æè·å° std::function ä¹ä¸ // ï¼è¿å¯è½å¸¦æ¥ä¸å¿ è¦çå¼éï¼ std::function<int(int)> func2 = [](int i) { return i + 4; }; std::cout << "func2: " << func2(6) << '\n'; }
è¾åºï¼
c: 5 6 7 func1: 10 func2: 10
ç¼ºé·æ¥å
ä¸åæ´æ¹è¡ä¸ºçç¼ºé·æ¥å追溯å°åºç¨äºä»¥ååºçç C++ æ åã
| DR | åºç¨äº | åºçæ¶çè¡ä¸º | æ£ç¡®è¡ä¸º |
|---|---|---|---|
| CWG 975 | C++11 | ä» å½ lambda ä½å«æåæ¡ return è¯å¥æ¶ææ¨å¯¼éå ç operator() çè¿åç±»å | å¦åå¯¹äº C++14 è¿å auto ç彿°ä¸è¬æ¨å¯¼ |
| CWG 1891 | C++14 | éå 带æå¼ç½®çé»è®¤æé 彿°åéå«çå¤å¶/ç§»å¨æé 彿° | æ é»è®¤åé¢ç½®çå¤å¶/ç§»å¨ |
| CWG 1722 | C++14 | æ æè· lambda ç转æ¢å½æ°ææªææçå¼å¸¸è¯´æ | 转æ¢å½æ°ä¸º noexcept |
åé
| auto 说æç¬¦ | æå®ä¸ä¸ªç±è¡¨è¾¾å¼å®ä¹çç±»å(C++11) |
| (C++11) |
å
è£
å
·ææå®å½æ°è°ç¨ç¾åçä»»æç±»åçå¯è°ç¨å¯¹è±¡ (类模æ¿) |