-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathlambdas.html
More file actions
514 lines (414 loc) · 144 KB
/
lambdas.html
File metadata and controls
514 lines (414 loc) · 144 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>C++ | Lambdas</title>
<meta name="generator" content="VuePress 1.8.2">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="description" content="What is a lambda expression?, Specifying the return type, Capture by value, Recursive lambdas, Default capture, Capture by reference, Generic lambdas, Class lambdas and capture of this, Generalized capture, Conversion to function pointer, Using lambdas for inline parameter pack unpacking, Porting lambda functions to C++03 using functors">
<meta property="og:site_name" content="DevTut">
<meta property="og:title" content="C++ | Lambdas">
<meta property="og:description" content="What is a lambda expression?, Specifying the return type, Capture by value, Recursive lambdas, Default capture, Capture by reference, Generic lambdas, Class lambdas and capture of this, Generalized capture, Conversion to function pointer, Using lambdas for inline parameter pack unpacking, Porting lambda functions to C++03 using functors">
<meta property="og:type" content="article">
<meta property="og:url" content="/cpp/lambdas.html">
<meta property="og:image" content="/logo.png">
<meta name="twitter:title" content="C++ | Lambdas">
<meta name="twitter:description" content="What is a lambda expression?, Specifying the return type, Capture by value, Recursive lambdas, Default capture, Capture by reference, Generic lambdas, Class lambdas and capture of this, Generalized capture, Conversion to function pointer, Using lambdas for inline parameter pack unpacking, Porting lambda functions to C++03 using functors">
<meta name="twitter:url" content="/cpp/lambdas.html">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="/logo.png">
<meta name="theme-color" content="#ffffff">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="msapplication-TileImage" content="/mstile-150x150.png">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="google-site-verification" content="76_rKXgwMVIjd-axJC_1zPV9OS4mEjvtgjYOWVkAdnQ">
<link rel="preload" href="/assets/css/0.styles.60619e34.css" as="style"><link rel="preload" href="/assets/js/app.1779e102.js" as="script"><link rel="preload" href="/assets/js/3.2cfa8016.js" as="script"><link rel="preload" href="/assets/js/669.4e6cb383.js" as="script">
<link rel="stylesheet" href="/assets/css/0.styles.60619e34.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">DevTut</span></a> <div class="links"><form id="search-form" role="search" class="algolia-search-wrapper search-box"><input id="algolia-search-input" class="search-query"></form> <nav class="nav-links can-hide"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>C++</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/cpp/" aria-current="page" class="sidebar-link">Disclaimer</a></li><li><a href="/cpp/getting-started-with-cpp.html" class="sidebar-link">Getting started with C++</a></li><li><a href="/cpp/literals.html" class="sidebar-link">Literals</a></li><li><a href="/cpp/operator-precedence.html" class="sidebar-link">operator precedence</a></li><li><a href="/cpp/floating-point-arithmetic.html" class="sidebar-link">Floating Point Arithmetic</a></li><li><a href="/cpp/bit-operators.html" class="sidebar-link">Bit Operators</a></li><li><a href="/cpp/bit-manipulation.html" class="sidebar-link">Bit Manipulation</a></li><li><a href="/cpp/bit-fields.html" class="sidebar-link">Bit fields</a></li><li><a href="/cpp/arrays.html" class="sidebar-link">Arrays</a></li><li><a href="/cpp/iterators.html" class="sidebar-link">Iterators</a></li><li><a href="/cpp/basic-input-output-in-c.html" class="sidebar-link">Basic input/output in c++</a></li><li><a href="/cpp/loops.html" class="sidebar-link">Loops</a></li><li><a href="/cpp/file-i-o.html" class="sidebar-link">File I/O</a></li><li><a href="/cpp/cpp-streams.html" class="sidebar-link">C++ Streams</a></li><li><a href="/cpp/stream-manipulators.html" class="sidebar-link">Stream manipulators</a></li><li><a href="/cpp/flow-control.html" class="sidebar-link">Flow Control</a></li><li><a href="/cpp/metaprogramming.html" class="sidebar-link">Metaprogramming</a></li><li><a href="/cpp/const-keyword.html" class="sidebar-link">const keyword</a></li><li><a href="/cpp/mutable-keyword.html" class="sidebar-link">mutable keyword</a></li><li><a href="/cpp/friend-keyword.html" class="sidebar-link">Friend keyword</a></li><li><a href="/cpp/type-keywords.html" class="sidebar-link">Type Keywords</a></li><li><a href="/cpp/basic-type-keywords.html" class="sidebar-link">Basic Type Keywords</a></li><li><a href="/cpp/variable-declaration-keywords.html" class="sidebar-link">Variable Declaration Keywords</a></li><li><a href="/cpp/keywords.html" class="sidebar-link">Keywords</a></li><li><a href="/cpp/returning-several-values-from-a-function.html" class="sidebar-link">Returning several values from a function</a></li><li><a href="/cpp/polymorphism.html" class="sidebar-link">Polymorphism</a></li><li><a href="/cpp/references.html" class="sidebar-link">References</a></li><li><a href="/cpp/value-and-reference-semantics.html" class="sidebar-link">Value and Reference Semantics</a></li><li><a href="/cpp/c-function-call-by-value-vs-call-by-reference.html" class="sidebar-link">C++ function "call by value" vs. "call by reference"</a></li><li><a href="/cpp/copying-vs-assignment.html" class="sidebar-link">Copying vs Assignment</a></li><li><a href="/cpp/pointers.html" class="sidebar-link">Pointers</a></li><li><a href="/cpp/pointers-to-members.html" class="sidebar-link">Pointers to members</a></li><li><a href="/cpp/the-this-pointer.html" class="sidebar-link">The This Pointer</a></li><li><a href="/cpp/smart-pointers.html" class="sidebar-link">Smart Pointers</a></li><li><a href="/cpp/classes-structures.html" class="sidebar-link">Classes/Structures</a></li><li><a href="/cpp/function-overloading.html" class="sidebar-link">Function Overloading</a></li><li><a href="/cpp/operator-overloading.html" class="sidebar-link">Operator Overloading</a></li><li><a href="/cpp/function-template-overloading.html" class="sidebar-link">Function Template Overloading</a></li><li><a href="/cpp/virtual-member-functions.html" class="sidebar-link">Virtual Member Functions</a></li><li><a href="/cpp/inline-functions.html" class="sidebar-link">Inline functions</a></li><li><a href="/cpp/special-member-functions.html" class="sidebar-link">Special Member Functions</a></li><li><a href="/cpp/non-static-member-functions.html" class="sidebar-link">Non-Static Member Functions</a></li><li><a href="/cpp/constant-class-member-functions.html" class="sidebar-link">Constant class member functions</a></li><li><a href="/cpp/c-containers.html" class="sidebar-link">C++ Containers</a></li><li><a href="/cpp/namespaces.html" class="sidebar-link">Namespaces</a></li><li><a href="/cpp/header-files.html" class="sidebar-link">Header Files</a></li><li><a href="/cpp/using-declaration.html" class="sidebar-link">Using declaration</a></li><li><a href="/cpp/std-string.html" class="sidebar-link">std::string</a></li><li><a href="/cpp/std-array.html" class="sidebar-link">std::array</a></li><li><a href="/cpp/std-vector.html" class="sidebar-link">std::vector</a></li><li><a href="/cpp/std-map.html" class="sidebar-link">std::map</a></li><li><a href="/cpp/std-optional.html" class="sidebar-link">std::optional</a></li><li><a href="/cpp/std-function-to-wrap-any-element-that-is-callable.html" class="sidebar-link">std::function: To wrap any element that is callable</a></li><li><a href="/cpp/std-forward-list.html" class="sidebar-link">std::forward_list</a></li><li><a href="/cpp/std-pair.html" class="sidebar-link">std::pair</a></li><li><a href="/cpp/std-atomics.html" class="sidebar-link">std::atomics</a></li><li><a href="/cpp/std-variant.html" class="sidebar-link">std::variant</a></li><li><a href="/cpp/std-iomanip.html" class="sidebar-link">std::iomanip</a></li><li><a href="/cpp/std-any.html" class="sidebar-link">std::any</a></li><li><a href="/cpp/std-set-and-std-multiset.html" class="sidebar-link">std::set and std::multiset</a></li><li><a href="/cpp/std-integer-sequence.html" class="sidebar-link">std::integer_sequence</a></li><li><a href="/cpp/using-std-unordered-map.html" class="sidebar-link">Using std::unordered_map</a></li><li><a href="/cpp/standard-library-algorithms.html" class="sidebar-link">Standard Library Algorithms</a></li><li><a href="/cpp/the-iso-c-standard.html" class="sidebar-link">The ISO C++ Standard</a></li><li><a href="/cpp/inline-variables.html" class="sidebar-link">Inline variables</a></li><li><a href="/cpp/random-number-generation.html" class="sidebar-link">Random number generation</a></li><li><a href="/cpp/date-and-time-using-chrono-header.html" class="sidebar-link">Date and time using header</a></li><li><a href="/cpp/sorting.html" class="sidebar-link">Sorting</a></li><li><a href="/cpp/enumeration.html" class="sidebar-link">Enumeration</a></li><li><a href="/cpp/iteration.html" class="sidebar-link">Iteration</a></li><li><a href="/cpp/regular-expressions.html" class="sidebar-link">Regular expressions</a></li><li><a href="/cpp/implementation-defined-behavior.html" class="sidebar-link">Implementation-defined behavior</a></li><li><a href="/cpp/exceptions.html" class="sidebar-link">Exceptions</a></li><li><a href="/cpp/lambdas.html" aria-current="page" class="active sidebar-link">Lambdas</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#what-is-a-lambda-expression" class="sidebar-link">What is a lambda expression?</a></li><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#specifying-the-return-type" class="sidebar-link">Specifying the return type</a></li><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#capture-by-value" class="sidebar-link">Capture by value</a></li><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#recursive-lambdas" class="sidebar-link">Recursive lambdas</a></li><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#default-capture" class="sidebar-link">Default capture</a></li><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#capture-by-reference" class="sidebar-link">Capture by reference</a></li><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#generic-lambdas" class="sidebar-link">Generic lambdas</a></li><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#class-lambdas-and-capture-of-this" class="sidebar-link">Class lambdas and capture of this</a></li><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#generalized-capture" class="sidebar-link">Generalized capture</a></li><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#conversion-to-function-pointer" class="sidebar-link">Conversion to function pointer</a></li><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#using-lambdas-for-inline-parameter-pack-unpacking" class="sidebar-link">Using lambdas for inline parameter pack unpacking</a></li><li class="sidebar-sub-header"><a href="/cpp/lambdas.html#porting-lambda-functions-to-c-03-using-functors" class="sidebar-link">Porting lambda functions to C++03 using functors</a></li></ul></li><li><a href="/cpp/value-categories.html" class="sidebar-link">Value Categories</a></li><li><a href="/cpp/preprocessor.html" class="sidebar-link">Preprocessor</a></li><li><a href="/cpp/data-structures-in-c.html" class="sidebar-link">Data Structures in C++</a></li><li><a href="/cpp/templates.html" class="sidebar-link">Templates</a></li><li><a href="/cpp/expression-templates.html" class="sidebar-link">Expression templates</a></li><li><a href="/cpp/curiously-recurring-template-pattern-crtp.html" class="sidebar-link">Curiously Recurring Template Pattern (CRTP)</a></li><li><a href="/cpp/threading.html" class="sidebar-link">Threading</a></li><li><a href="/cpp/thread-synchronization-structures.html" class="sidebar-link">Thread synchronization structures</a></li><li><a href="/cpp/the-rule-of-three-five-and-zero.html" class="sidebar-link">The Rule of Three, Five, And Zero</a></li><li><a href="/cpp/raii-resource-acquisition-is-initialization.html" class="sidebar-link">RAII: Resource Acquisition Is Initialization</a></li><li><a href="/cpp/rtti-run-time-type-information.html" class="sidebar-link">RTTI: Run-Time Type Information</a></li><li><a href="/cpp/mutexes.html" class="sidebar-link">Mutexes</a></li><li><a href="/cpp/recursive-mutex.html" class="sidebar-link">Recursive Mutex</a></li><li><a href="/cpp/semaphore.html" class="sidebar-link">Semaphore</a></li><li><a href="/cpp/futures-and-promises.html" class="sidebar-link">Futures and Promises</a></li><li><a href="/cpp/atomic-types.html" class="sidebar-link">Atomic Types</a></li><li><a href="/cpp/type-erasure.html" class="sidebar-link">Type Erasure</a></li><li><a href="/cpp/explicit-type-conversions.html" class="sidebar-link">Explicit type conversions</a></li><li><a href="/cpp/unnamed-types.html" class="sidebar-link">Unnamed types</a></li><li><a href="/cpp/type-traits.html" class="sidebar-link">Type Traits</a></li><li><a href="/cpp/return-type-covariance.html" class="sidebar-link">Return Type Covariance</a></li><li><a href="/cpp/layout-of-object-types.html" class="sidebar-link">Layout of object types</a></li><li><a href="/cpp/type-inference.html" class="sidebar-link">Type Inference</a></li><li><a href="/cpp/typedef-and-type-aliases.html" class="sidebar-link">Typedef and type aliases</a></li><li><a href="/cpp/type-deduction.html" class="sidebar-link">type deduction</a></li><li><a href="/cpp/trailing-return-type.html" class="sidebar-link">Trailing return type</a></li><li><a href="/cpp/alignment.html" class="sidebar-link">Alignment</a></li><li><a href="/cpp/perfect-forwarding.html" class="sidebar-link">Perfect Forwarding</a></li><li><a href="/cpp/decltype.html" class="sidebar-link">decltype</a></li><li><a href="/cpp/sfinae-substitution-failure-is-not-an-error.html" class="sidebar-link">SFINAE (Substitution Failure Is Not An Error)</a></li><li><a href="/cpp/undefined-behavior.html" class="sidebar-link">Undefined Behavior</a></li><li><a href="/cpp/overload-resolution.html" class="sidebar-link">Overload resolution</a></li><li><a href="/cpp/move-semantics.html" class="sidebar-link">Move Semantics</a></li><li><a href="/cpp/pimpl-idiom.html" class="sidebar-link">Pimpl Idiom</a></li><li><a href="/cpp/auto.html" class="sidebar-link">auto</a></li><li><a href="/cpp/copy-elision.html" class="sidebar-link">Copy Elision</a></li><li><a href="/cpp/fold-expressions.html" class="sidebar-link">Fold Expressions</a></li><li><a href="/cpp/unions.html" class="sidebar-link">Unions</a></li><li><a href="/cpp/design-pattern-implementation-in-c.html" class="sidebar-link">Design pattern implementation in C++</a></li><li><a href="/cpp/singleton-design-pattern.html" class="sidebar-link">Singleton Design Pattern</a></li><li><a href="/cpp/user-defined-literals.html" class="sidebar-link">User-Defined Literals</a></li><li><a href="/cpp/memory-management.html" class="sidebar-link">Memory management</a></li><li><a href="/cpp/c-11-memory-model.html" class="sidebar-link">C++11 Memory Model</a></li><li><a href="/cpp/scopes.html" class="sidebar-link">Scopes</a></li><li><a href="/cpp/static-assert.html" class="sidebar-link">static_assert</a></li><li><a href="/cpp/constexpr.html" class="sidebar-link">constexpr</a></li><li><a href="/cpp/one-definition-rule-odr.html" class="sidebar-link">One Definition Rule (ODR)</a></li><li><a href="/cpp/unspecified-behavior.html" class="sidebar-link">Unspecified behavior</a></li><li><a href="/cpp/argument-dependent-name-lookup.html" class="sidebar-link">Argument Dependent Name Lookup</a></li><li><a href="/cpp/attributes.html" class="sidebar-link">Attributes</a></li><li><a href="/cpp/recursion-in-c.html" class="sidebar-link">Recursion in C++</a></li><li><a href="/cpp/arithmitic-metaprogramming.html" class="sidebar-link">Arithmitic Metaprogramming</a></li><li><a href="/cpp/callable-objects.html" class="sidebar-link">Callable Objects</a></li><li><a href="/cpp/client-server-examples.html" class="sidebar-link">Client server examples</a></li><li><a href="/cpp/const-correctness.html" class="sidebar-link">Const Correctness</a></li><li><a href="/cpp/parameter-packs.html" class="sidebar-link">Parameter packs</a></li><li><a href="/cpp/build-systems.html" class="sidebar-link">Build Systems</a></li><li><a href="/cpp/concurrency-with-openmp.html" class="sidebar-link">Concurrency With OpenMP</a></li><li><a href="/cpp/resource-management.html" class="sidebar-link">Resource Management</a></li><li><a href="/cpp/storage-class-specifiers.html" class="sidebar-link">Storage class specifiers</a></li><li><a href="/cpp/linkage-specifications.html" class="sidebar-link">Linkage specifications</a></li><li><a href="/cpp/digit-separators.html" class="sidebar-link">Digit separators</a></li><li><a href="/cpp/c-incompatibilities.html" class="sidebar-link">C incompatibilities</a></li><li><a href="/cpp/side-by-side-comparisons-of-classic-c-examples-solved-via-c-vs-c-11-vs-c-14-vs-c-17.html" class="sidebar-link">Side by Side Comparisons of classic C++ examples solved via C++ vs C++11 vs C++14 vs C++17</a></li><li><a href="/cpp/compiling-and-building.html" class="sidebar-link">Compiling and Building</a></li><li><a href="/cpp/common-compile-linker-errors-gcc.html" class="sidebar-link">Common compile/linker errors (GCC)</a></li><li><a href="/cpp/more-undefined-behaviors-in-c.html" class="sidebar-link">More undefined behaviors in C++</a></li><li><a href="/cpp/unit-testing-in-c.html" class="sidebar-link">Unit Testing in C++</a></li><li><a href="/cpp/c-debugging-and-debug-prevention-tools-techniques.html" class="sidebar-link">C++ Debugging and Debug-prevention Tools & Techniques</a></li><li><a href="/cpp/optimization-in-c.html" class="sidebar-link">Optimization in C++</a></li><li><a href="/cpp/optimization.html" class="sidebar-link">Optimization</a></li><li><a href="/cpp/profiling.html" class="sidebar-link">Profiling</a></li><li><a href="/cpp/refactoring-techniques.html" class="sidebar-link">Refactoring Techniques</a></li><li><a href="/cpp/internationalization-in-c.html" class="sidebar-link">Internationalization in C++</a></li><li><a href="/cpp/contributors.html" class="sidebar-link">The Contributors</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="lambdas"><a href="#lambdas" class="header-anchor">#</a> Lambdas</h1> <h2 id="what-is-a-lambda-expression"><a href="#what-is-a-lambda-expression" class="header-anchor">#</a> What is a lambda expression?</h2> <p>A <strong>lambda expression</strong> provides a concise way to create simple function objects. A lambda expression is a prvalue whose result object is called <a href="https://en.wikipedia.org/wiki/Closure_(computer_programming)" target="_blank" rel="noopener noreferrer">closure object<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>, which behaves like a function object.</p> <p>The name 'lambda expression' originates from <a href="https://en.wikipedia.org/wiki/Lambda_calculus" target="_blank" rel="noopener noreferrer">lambda calculus<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>, which is a mathematical formalism invented in the 1930s by Alonzo Church to investigate questions about logic and computability. Lambda calculus formed the basis of <a href="https://en.wikipedia.org/wiki/Lisp_(programming_language)" target="_blank" rel="noopener noreferrer">LISP<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>, a functional programming language. Compared to lambda calculus and LISP, C++ lambda expressions share the properties of being unnamed, and to capture variables from the surrounding context, but they lack the ability to operate on and return functions.</p> <p>A lambda expression is often used as an argument to functions that take a callable object. That can be simpler than creating a named function, which would be only used when passed as the argument. In such cases, lambda expressions are generally preferred because they allow defining the function objects inline.</p> <p>A lambda consists typically of three parts: a capture list <code>[]</code>, an optional parameter list <code>()</code> and a body <code>{}</code>, all of which can be empty:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// An empty lambda, which does and returns nothing</span>
</code></pre></div><p><strong>Capture list</strong></p> <p><code>[]</code> is the <strong>capture list</strong>. By default, variables of the enclosing scope cannot be accessed by a lambda. <strong>Capturing</strong> a variable makes it accessible inside the lambda, either <a href="http://stackoverflow.com/documentation/c%2b%2b/572/lambdas/1856/capture-by-value#t=201607271323349545754" target="_blank" rel="noopener noreferrer">as a copy<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> or <a href="http://stackoverflow.com/documentation/c%2b%2b/572/lambdas/1951/capture-by-reference#t=201607271323349545754" target="_blank" rel="noopener noreferrer">as a reference<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>. Captured variables become a part of the lambda; in contrast to function arguments, they do not have to be passed when calling the lambda.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// Define an integer variable</span>
<span class="token keyword">auto</span> f <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a<span class="token operator">*</span><span class="token number">9</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// Error: 'a' cannot be accessed</span>
<span class="token keyword">auto</span> f <span class="token operator">=</span> <span class="token punctuation">[</span>a<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a<span class="token operator">*</span><span class="token number">9</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// OK, 'a' is "captured" by value</span>
<span class="token keyword">auto</span> f <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">&</span>a<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// OK, 'a' is "captured" by reference</span>
<span class="token comment">// Note: It is the responsibility of the programmer</span>
<span class="token comment">// to ensure that a is not destroyed before the</span>
<span class="token comment">// lambda is called.</span>
<span class="token keyword">auto</span> b <span class="token operator">=</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Call the lambda function. a is taken from the capture list and not passed here.</span>
</code></pre></div><p><strong>Parameter list</strong></p> <p><code>()</code> is the <strong>parameter list</strong>, which is almost the same as in regular functions. If the lambda takes no arguments, these parentheses can be omitted (except if you need to declare the lambda <code>mutable</code>). These two lambdas are equivalent:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> call_foo <span class="token operator">=</span> <span class="token punctuation">[</span>x<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> x<span class="token punctuation">.</span><span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> call_foo2 <span class="token operator">=</span> <span class="token punctuation">[</span>x<span class="token punctuation">]</span><span class="token punctuation">{</span> x<span class="token punctuation">.</span><span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>The parameter list can use the placeholder type <code>auto</code> instead of actual types. By doing so, this argument behaves like a template parameter of a function template. Following lambdas are equivalent when you want to sort a vector in generic code:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> sort_cpp11 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>T<span class="token operator">></span><span class="token double-colon punctuation">::</span>const_reference lhs<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>T<span class="token operator">></span><span class="token double-colon punctuation">::</span>const_reference rhs<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> lhs <span class="token operator"><</span> rhs<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> sort_cpp14 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">auto</span> <span class="token operator">&</span>lhs<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">auto</span> <span class="token operator">&</span>rhs<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> lhs <span class="token operator"><</span> rhs<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>Function body</strong></p> <p><code>{}</code> is the <strong>body</strong>, which is the same as in regular functions.</p> <p><strong>Calling a lambda</strong></p> <p>A lambda expression's result object is a <a href="https://en.wikipedia.org/wiki/Closure_(computer_programming)" target="_blank" rel="noopener noreferrer">closure<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>, which can be called using the <code>operator()</code> (as with other function objects):</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">int</span> multiplier <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> timesFive <span class="token operator">=</span> <span class="token punctuation">[</span>multiplier<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> a<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">*</span> multiplier<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
std<span class="token double-colon punctuation">::</span>out <span class="token operator"><<</span> <span class="token function">timesFive</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Prints 10</span>
multiplier <span class="token operator">=</span> <span class="token number">15</span><span class="token punctuation">;</span>
std<span class="token double-colon punctuation">::</span>out <span class="token operator"><<</span> <span class="token function">timesFive</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Still prints 2*5 == 10</span>
</code></pre></div><p><strong>Return Type</strong></p> <p>By default, the return type of a lambda expression is deduced.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>In this case the return type is <code>bool</code>.</p> <p>You can also manually specify the return type using the following syntax:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token keyword">bool</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>Mutable Lambda</strong></p> <p>Objects captured by value in the lambda are by default immutable. This is because the <code>operator()</code> of the generated closure object is <code>const</code> by default.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> func <span class="token operator">=</span> <span class="token punctuation">[</span>c <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token operator">++</span>c<span class="token punctuation">;</span> std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> c<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// fails to compile because ++c</span>
<span class="token comment">// tries to mutate the state of</span>
<span class="token comment">// the lambda.</span>
</code></pre></div><p>Modifying can be allowed by using the keyword <code>mutable</code>, which make the closer object's <code>operator()</code> non-<code>const</code>:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> func <span class="token operator">=</span> <span class="token punctuation">[</span>c <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">mutable</span> <span class="token punctuation">{</span><span class="token operator">++</span>c<span class="token punctuation">;</span> std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> c<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>If used together with the return type, <code>mutable</code> comes before it.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> func <span class="token operator">=</span> <span class="token punctuation">[</span>c <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">mutable</span> <span class="token operator">-></span> <span class="token keyword">int</span> <span class="token punctuation">{</span><span class="token operator">++</span>c<span class="token punctuation">;</span> std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> c<span class="token punctuation">;</span> <span class="token keyword">return</span> c<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>An example to illustrate the usefulness of lambdas</strong></p> <p>Before C++11:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// Generic functor used for comparison</span>
<span class="token keyword">struct</span> <span class="token class-name">islessthan</span>
<span class="token punctuation">{</span>
<span class="token function">islessthan</span><span class="token punctuation">(</span><span class="token keyword">int</span> threshold<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">_threshold</span><span class="token punctuation">(</span>threshold<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">bool</span> <span class="token keyword">operator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">int</span> value<span class="token punctuation">)</span> <span class="token keyword">const</span>
<span class="token punctuation">{</span>
<span class="token keyword">return</span> value <span class="token operator"><</span> _threshold<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">private</span><span class="token operator">:</span>
<span class="token keyword">int</span> _threshold<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// Declare a vector</span>
<span class="token keyword">const</span> <span class="token keyword">int</span> arr<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span><span class="token keyword">int</span><span class="token operator">></span> <span class="token function">vec</span><span class="token punctuation">(</span>arr<span class="token punctuation">,</span> arr<span class="token operator">+</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Find a number that's less than a given input (assume this would have been function input)</span>
<span class="token keyword">int</span> threshold <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span><span class="token keyword">int</span><span class="token operator">></span><span class="token double-colon punctuation">::</span>iterator it <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">find_if</span><span class="token punctuation">(</span>vec<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> vec<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">islessthan</span><span class="token punctuation">(</span>threshold<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Since C++11:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// Declare a vector</span>
std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span><span class="token keyword">int</span><span class="token operator">></span> vec<span class="token punctuation">{</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// Find a number that's less than a given input (assume this would have been function input)</span>
<span class="token keyword">int</span> threshold <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> it <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">find_if</span><span class="token punctuation">(</span>vec<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> vec<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>threshold<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> value<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> value <span class="token operator"><</span> threshold<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="specifying-the-return-type"><a href="#specifying-the-return-type" class="header-anchor">#</a> Specifying the return type</h2> <p>For lambdas with a single return statement, or multiple return statements whose expressions are of the same type, the compiler can deduce the return type:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// Returns bool, because "value > 10" is a comparison which yields a Boolean result</span>
<span class="token keyword">auto</span> l <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> value<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> value <span class="token operator">></span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>For lambdas with multiple return statements of <strong>different</strong> types, the compiler can't deduce the return type:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// error: return types must match if lambda has unspecified return type</span>
<span class="token keyword">auto</span> l <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> value<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token number">1.5</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>In this case you have to specify the return type explicitly:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// The return type is specified explicitly as 'double'</span>
<span class="token keyword">auto</span> l <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> value<span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token keyword">double</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token number">1.5</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>The rules for this match the rules for <code>auto</code> type deduction. Lambdas without explicitly specified return types never return references, so if a reference type is desired it must be explicitly specified as well:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> copy <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span>X<span class="token operator">&</span> x<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> x<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// 'copy' returns an X, so copies its input</span>
<span class="token keyword">auto</span> ref <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span>X<span class="token operator">&</span> x<span class="token punctuation">)</span> <span class="token operator">-></span> X<span class="token operator">&</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> x<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// 'ref' returns an X&, no copy</span>
</code></pre></div><h2 id="capture-by-value"><a href="#capture-by-value" class="header-anchor">#</a> Capture by value</h2> <p>If you specify the variable's name in the capture list, the lambda will capture it by value. This means that the generated closure type for the lambda stores a copy of the variable. This also requires that the variable's type be <strong>copy-constructible</strong>:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">[</span>a<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> a<span class="token punctuation">;</span> <span class="token comment">// Ok, 'a' is captured by value</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> p <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">unique_ptr</span><span class="token generic class-name"><span class="token operator"><</span>T<span class="token operator">></span></span></span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">[</span>p<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Compile error; `unique_ptr` is not copy-constructible</span>
<span class="token keyword">return</span> p<span class="token operator">-></span><span class="token function">createWidget</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>From C++14 on, it is possible to initialize variables on the spot. This allows move only types to be captured in the lambda.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> p <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">make_unique</span><span class="token generic class-name"><span class="token operator"><</span>T<span class="token operator">></span></span></span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">[</span>p <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">move</span><span class="token punctuation">(</span>p<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> p<span class="token operator">-></span><span class="token function">createWidget</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>Even though a lambda captures variables by value when they are given by their name, such variables cannot be modified within the lambda body by default. This is because the closure type puts the lambda body in a declaration of <code>operator() const</code>.</p> <p>The <code>const</code> applies to accesses to member variables of the closure type, and captured variables that are members of the closure (all appearances to the contrary):</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">[</span>a<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// Illegal, 'a' is accessed via `const`</span>
<span class="token keyword">decltype</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span> a1 <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
a1 <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// valid: variable 'a1' is not const</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>To remove the <code>const</code>, you have to specify the keyword <code>mutable</code> on the lambda:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">[</span>a<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">mutable</span> <span class="token punctuation">{</span>
a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// OK, 'a' can be modified</span>
<span class="token keyword">return</span> a<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>Because <code>a</code> was captured by value, any modifications done by calling the lambda will not affect <code>a</code>. The value of <code>a</code> was copied into the lambda when it was constructed, so the lambda's copy of <code>a</code> is separate from the external <code>a</code> variable.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">5</span> <span class="token punctuation">;</span>
<span class="token keyword">auto</span> plus5Val <span class="token operator">=</span> <span class="token punctuation">[</span>a<span class="token punctuation">]</span> <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> <span class="token number">5</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span>
<span class="token keyword">auto</span> plus5Ref <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">&</span>a<span class="token punctuation">]</span> <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">return</span> a <span class="token operator">+</span> <span class="token number">5</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span>
a <span class="token operator">=</span> <span class="token number">7</span> <span class="token punctuation">;</span>
std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> a <span class="token operator"><<</span> <span class="token string">", value "</span> <span class="token operator"><<</span> <span class="token function">plus5Val</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator"><<</span> <span class="token string">", reference "</span> <span class="token operator"><<</span> <span class="token function">plus5Ref</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">;</span>
<span class="token comment">// The result will be "7, value 10, reference 12"</span>
</code></pre></div><h2 id="recursive-lambdas"><a href="#recursive-lambdas" class="header-anchor">#</a> Recursive lambdas</h2> <p>Let's say we wish to write Euclid's <code>gcd()</code> as a lambda. As a function, it is:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">int</span> <span class="token function">gcd</span><span class="token punctuation">(</span><span class="token keyword">int</span> a<span class="token punctuation">,</span> <span class="token keyword">int</span> b<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> b <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">?</span> a <span class="token operator">:</span> <span class="token function">gcd</span><span class="token punctuation">(</span>b<span class="token punctuation">,</span> a<span class="token operator">%</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>But a lambda cannot be recursive, it has no way to invoke itself. A lambda has no name and using <code>this</code> within the body of a lambda refers to a captured <code>this</code> (assuming the lambda is created in the body of a member function, otherwise it is an error). So how do we solve this problem?</p> <h3 id="use-std-function"><a href="#use-std-function" class="header-anchor">#</a> Use <code>std::function</code></h3> <p>We can have a lambda capture a reference to a not-yet constructed <code>std::function</code>:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code>std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">int</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">)</span><span class="token operator">></span> gcd <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">&</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> a<span class="token punctuation">,</span> <span class="token keyword">int</span> b<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">return</span> b <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">?</span> a <span class="token operator">:</span> <span class="token function">gcd</span><span class="token punctuation">(</span>b<span class="token punctuation">,</span> a<span class="token operator">%</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>This works, but should be used sparingly. It's slow (we're using type erasure now instead of a direct function call), it's fragile (copying <code>gcd</code> or returning <code>gcd</code> will break since the lambda refers to the original object), and it won't work with generic lambdas.</p> <h3 id="using-two-smart-pointers"><a href="#using-two-smart-pointers" class="header-anchor">#</a> Using two smart pointers:</h3> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> gcd_self <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>make_shared<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>unique_ptr<span class="token operator"><</span> std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">int</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">)</span><span class="token operator">></span> <span class="token operator">>></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">*</span>gcd_self <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">make_unique</span><span class="token generic class-name"><span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>function<span class="token operator"><</span><span class="token keyword">int</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">)</span><span class="token operator">>></span></span></span><span class="token punctuation">(</span>
<span class="token punctuation">[</span>gcd_self<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> a<span class="token punctuation">,</span> <span class="token keyword">int</span> b<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">return</span> b <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">?</span> a <span class="token operator">:</span> <span class="token punctuation">(</span><span class="token operator">*</span><span class="token operator">*</span>gcd_self<span class="token punctuation">)</span><span class="token punctuation">(</span>b<span class="token punctuation">,</span> a<span class="token operator">%</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>This adds a lot of indirection (which is overhead), but it can be copied/returned, and all copies share state. It does let you return the lambda, and is otherwise less fragile than the above solution.</p> <h3 id="use-a-y-combinator"><a href="#use-a-y-combinator" class="header-anchor">#</a> Use a Y-combinator</h3> <p>With the help of a short utility struct, we can solve all of these problems:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">template</span> <span class="token operator"><</span><span class="token keyword">class</span> <span class="token class-name">F</span><span class="token operator">></span>
<span class="token keyword">struct</span> <span class="token class-name">y_combinator</span> <span class="token punctuation">{</span>
F f<span class="token punctuation">;</span> <span class="token comment">// the lambda will be stored here</span>
<span class="token comment">// a forwarding operator():</span>
<span class="token keyword">template</span> <span class="token operator"><</span><span class="token keyword">class</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> Args<span class="token operator">></span>
<span class="token keyword">decltype</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token punctuation">)</span> <span class="token keyword">operator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span>Args<span class="token operator">&&</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> args<span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span>
<span class="token comment">// we pass ourselves to f, then the arguments.</span>
<span class="token comment">// the lambda should take the first argument as `auto&& recurse` or similar.</span>
<span class="token keyword">return</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token keyword">this</span><span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">forward</span><span class="token generic class-name"><span class="token operator"><</span>Args<span class="token operator">></span></span></span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// helper function that deduces the type of the lambda:</span>
<span class="token keyword">template</span> <span class="token operator"><</span><span class="token keyword">class</span> <span class="token class-name">F</span><span class="token operator">></span>
y_combinator<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>decay_t<span class="token operator"><</span>F<span class="token operator">>></span> <span class="token function">make_y_combinator</span><span class="token punctuation">(</span>F<span class="token operator">&&</span> f<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span>std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">forward</span><span class="token generic class-name"><span class="token operator"><</span>F<span class="token operator">></span></span></span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// (Be aware that in C++17 we can do better than a `make_` function)</span>
</code></pre></div><p>we can implement our <code>gcd</code> as:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> gcd <span class="token operator">=</span> <span class="token function">make_y_combinator</span><span class="token punctuation">(</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&&</span> gcd<span class="token punctuation">,</span> <span class="token keyword">int</span> a<span class="token punctuation">,</span> <span class="token keyword">int</span> b<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">return</span> b <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">?</span> a <span class="token operator">:</span> <span class="token function">gcd</span><span class="token punctuation">(</span>b<span class="token punctuation">,</span> a<span class="token operator">%</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>The <code>y_combinator</code> is a concept from the lambda calculus that lets you have recursion without being able to name yourself until you are defined. This is exactly the problem lambdas have.</p> <p>You create a lambda that takes "recurse" as its first argument. When you want to recurse, you pass the arguments to recurse.</p> <p>The <code>y_combinator</code> then returns a function object that calls that function with its arguments, but with a suitable "recurse" object (namely the <code>y_combinator</code> itself) as its first argument. It forwards the rest of the arguments you call the <code>y_combinator</code> with to the lambda as well.</p> <p>In short:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> foo <span class="token operator">=</span> <span class="token function">make_y_combinator</span><span class="token punctuation">(</span> <span class="token punctuation">[</span><span class="token operator">&</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&&</span> recurse<span class="token punctuation">,</span> some arguments<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// write body that processes some arguments</span>
<span class="token comment">// when you want to recurse, call recurse(some other arguments)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>and you have recursion in a lambda with no serious restrictions or significant overhead.</p> <h2 id="default-capture"><a href="#default-capture" class="header-anchor">#</a> Default capture</h2> <p>By default, local variables that are not explicitly specified in the capture list, cannot be accessed from within the lambda body. However, it is possible to implicitly capture variables named by the lambda body:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token comment">// Default capture by value</span>
<span class="token punctuation">[</span><span class="token operator">=</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// OK; a and b are captured by value</span>
<span class="token comment">// Default capture by reference</span>
<span class="token punctuation">[</span><span class="token operator">&</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// OK; a and b are captured by reference</span>
</code></pre></div><p>Explicit capturing can still be done alongside implicit default capturing. The explicit capture definition will override the default capture:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> b <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">[</span><span class="token operator">=</span><span class="token punctuation">,</span> <span class="token operator">&</span>b<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// Illegal; 'a' is capture by value, and lambda is not 'mutable'</span>
b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// OK; 'b' is captured by reference</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="capture-by-reference"><a href="#capture-by-reference" class="header-anchor">#</a> Capture by reference</h2> <p>If you precede a local variable's name with an <code>&</code>, then the variable will be captured by reference. Conceptually, this means that the lambda's closure type will have a reference variable, initialized as a reference to the corresponding variable from outside of the lambda's scope. Any use of the variable in the lambda body will refer to the original variable:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// Declare variable 'a'</span>
<span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token comment">// Declare a lambda which captures 'a' by reference</span>
<span class="token keyword">auto</span> set <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">&</span>a<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token function">set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">assert</span><span class="token punctuation">(</span>a <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>The keyword <code>mutable</code> is not needed, because <code>a</code> itself is not <code>const</code>.</p> <p>Of course, capturing by reference means that the lambda <strong>must not</strong> escape the scope of the variables it captures. So you could call functions that take a function, but you must not call a function that will <strong>store</strong> the lambda beyond the scope of your references. And you must not return the lambda.</p> <h2 id="generic-lambdas"><a href="#generic-lambdas" class="header-anchor">#</a> Generic lambdas</h2> <p>Lambda functions can take arguments of arbitrary types. This allows a lambda to be more generic:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> twice <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span> x<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> x<span class="token operator">+</span>x<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token function">twice</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// i == 4</span>
std<span class="token double-colon punctuation">::</span>string s <span class="token operator">=</span> <span class="token function">twice</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// s == "hellohello"</span>
</code></pre></div><p>This is implemented in C++ by making the closure type's <code>operator()</code> overload a template function. The following type has equivalent behavior to the above lambda closure:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">struct</span> <span class="token class-name">_unique_lambda_type</span>
<span class="token punctuation">{</span>
<span class="token keyword">template</span><span class="token operator"><</span><span class="token keyword">typename</span> <span class="token class-name">T</span><span class="token operator">></span>
<span class="token keyword">auto</span> <span class="token keyword">operator</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>T x<span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span><span class="token keyword">return</span> x <span class="token operator">+</span> x<span class="token punctuation">;</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>Not all parameters in a generic lambda need be generic:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span> x<span class="token punctuation">,</span> <span class="token keyword">int</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">return</span> x <span class="token operator">+</span> y<span class="token punctuation">;</span><span class="token punctuation">}</span>
</code></pre></div><p>Here, <code>x</code> is deduced based on the first function argument, while <code>y</code> will always be <code>int</code>.</p> <p>Generic lambdas can take arguments by reference as well, using the usual rules for <code>auto</code> and <code>&</code>. If a generic parameter is taken as <code>auto&&</code>, this is a <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4164.pdf" target="_blank" rel="noopener noreferrer"><strong>forwarding</strong> reference<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> to the passed in argument and not an <a href="http://en.cppreference.com/w/cpp/language/reference" target="_blank" rel="noopener noreferrer"><strong>rvalue</strong> reference<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> lamb1 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token operator">&&</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">return</span> x <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> lamb2 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&&</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">return</span> x <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> x <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token function">lamb1</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Illegal; must use `std::move(x)` for `int&&` parameters.</span>
<span class="token function">lamb2</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Legal; the type of `x` is deduced as `int&`.</span>
</code></pre></div><p>Lambda functions can be variadic and perfectly forward their arguments:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> lam <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&&</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> args<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">return</span> <span class="token function">f</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">forward</span><span class="token generic class-name"><span class="token operator"><</span><span class="token keyword">decltype</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token operator">></span></span></span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>or:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> lam <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&&</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> args<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">return</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token keyword">decltype</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>which only works "properly" with variables of type <code>auto&&</code>.</p> <p>A strong reason to use generic lambdas is for visiting syntax.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code>boost<span class="token double-colon punctuation">::</span>variant<span class="token operator"><</span><span class="token keyword">int</span><span class="token punctuation">,</span> <span class="token keyword">double</span><span class="token operator">></span> value<span class="token punctuation">;</span>
<span class="token function">apply_visitor</span><span class="token punctuation">(</span>value<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token operator">&</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&&</span> e<span class="token punctuation">)</span><span class="token punctuation">{</span>
std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> e<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Here we are visiting in a polymorphic manner; but in other contexts, the names of the type we are passing isn't interesting:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code>mutex_wrapped<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>ostream<span class="token operator">&</span><span class="token operator">></span> os <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>cout<span class="token punctuation">;</span>
os<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">&</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&&</span> os<span class="token punctuation">)</span><span class="token punctuation">{</span>
os <span class="token operator"><<</span> <span class="token string">"hello world\n"</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Repeating the type of <code>std::ostream&</code> is noise here; it would be like having to mention the type of a variable every time you use it. Here we are creating a visitor, but no a polymorphic one; <code>auto</code> is used for the same reason you might use <code>auto</code> in a <code>for(:)</code> loop.</p> <h2 id="class-lambdas-and-capture-of-this"><a href="#class-lambdas-and-capture-of-this" class="header-anchor">#</a> Class lambdas and capture of this</h2> <p>A lambda expression evaluated in a class' member function is implicitly a friend of that class:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">class</span> <span class="token class-name">Foo</span>
<span class="token punctuation">{</span>
<span class="token keyword">private</span><span class="token operator">:</span>
<span class="token keyword">int</span> i<span class="token punctuation">;</span>
<span class="token keyword">public</span><span class="token operator">:</span>
<span class="token function">Foo</span><span class="token punctuation">(</span><span class="token keyword">int</span> val<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">i</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token comment">// definition of a member function</span>
<span class="token keyword">void</span> <span class="token function">Test</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token keyword">auto</span> lamb <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span>Foo <span class="token operator">&</span>foo<span class="token punctuation">,</span> <span class="token keyword">int</span> val<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token comment">// modification of a private member variable</span>
foo<span class="token punctuation">.</span>i <span class="token operator">=</span> val<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// lamb is allowed to access a private member, because it is a friend of Foo</span>
<span class="token function">lamb</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>Such a lambda is not only a friend of that class, it has the same access as the class it is declared within has.</p> <p>Lambdas can capture the <code>this</code> pointer which represents the object instance the outer function was called on. This is done by adding <code>this</code> to the capture list:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">class</span> <span class="token class-name">Foo</span>
<span class="token punctuation">{</span>
<span class="token keyword">private</span><span class="token operator">:</span>
<span class="token keyword">int</span> i<span class="token punctuation">;</span>
<span class="token keyword">public</span><span class="token operator">:</span>
<span class="token function">Foo</span><span class="token punctuation">(</span><span class="token keyword">int</span> val<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">i</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token function">Test</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token comment">// capture the this pointer by value</span>
<span class="token keyword">auto</span> lamb <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> val<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
i <span class="token operator">=</span> val<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token function">lamb</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>When <code>this</code> is captured, the lambda can use member names of its containing class as though it were in its containing class. So an implicit <code>this-></code> is applied to such members.</p> <p>Be aware that <code>this</code> is captured by value, but not the value of the type. It is captured by the value of <code>this</code>, which is a <strong>pointer</strong>. As such, the lambda does not <strong>own</strong> <code>this</code>. If the lambda out lives the lifetime of the object that created it, the lambda can become invalid.</p> <p>This also means that the lambda can modify <code>this</code> without being declared <code>mutable</code>. It is the pointer which is <code>const</code>, not the object being pointed to. That is, unless the outer member function was itself a <code>const</code> function.</p> <p>Also, be aware that the default capture clauses, both <code>[=]</code> and <code>[&]</code>, will <strong>also</strong> capture <code>this</code> implicitly. And they both capture it by the value of the pointer. Indeed, it is an error to specify <code>this</code> in the capture list when a default is given.</p> <p>Lambdas can capture a copy of the <code>this</code> object, created at the time the lambda is created. This is done by adding <code>*this</code> to the capture list:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">class</span> <span class="token class-name">Foo</span>
<span class="token punctuation">{</span>
<span class="token keyword">private</span><span class="token operator">:</span>
<span class="token keyword">int</span> i<span class="token punctuation">;</span>
<span class="token keyword">public</span><span class="token operator">:</span>
<span class="token function">Foo</span><span class="token punctuation">(</span><span class="token keyword">int</span> val<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">i</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">void</span> <span class="token function">Test</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token comment">// capture a copy of the object given by the this pointer</span>
<span class="token keyword">auto</span> lamb <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">*</span><span class="token keyword">this</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> val<span class="token punctuation">)</span> <span class="token keyword">mutable</span>
<span class="token punctuation">{</span>
i <span class="token operator">=</span> val<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token function">lamb</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// does not change this->i</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="generalized-capture"><a href="#generalized-capture" class="header-anchor">#</a> Generalized capture</h2> <p>Lambdas can capture expressions, rather than just variables. This permits lambdas to store move-only types:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> p <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">make_unique</span><span class="token generic class-name"><span class="token operator"><</span>T<span class="token operator">></span></span></span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> lamb <span class="token operator">=</span> <span class="token punctuation">[</span>p <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">move</span><span class="token punctuation">(</span>p<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">//Overrides capture-by-value of `p`.</span>
<span class="token punctuation">{</span>
p<span class="token operator">-></span><span class="token function">SomeFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>This moves the outer <code>p</code> variable into the lambda capture variable, also called <code>p</code>. <code>lamb</code> now owns the memory allocated by <code>make_unique</code>. Because the closure contains a type that is non-copyable, this means that <code>lamb</code> is itself non-copyable. But it can be moved:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> lamb_copy <span class="token operator">=</span> lamb<span class="token punctuation">;</span> <span class="token comment">//Illegal</span>
<span class="token keyword">auto</span> lamb_move <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">move</span><span class="token punctuation">(</span>lamb<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//legal.</span>
</code></pre></div><p>Now <code>lamb_move</code> owns the memory.</p> <p>Note that <code>std::function<></code> requires that the values stored be copyable. You can write your own <a href="https://stackoverflow.com/documentation/c%2b%2b/2872/type-erasure/18042/a-move-only-stdfunction#t=201608061624094409548" target="_blank" rel="noopener noreferrer">move-only-requiring <code>std::function</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>, or you could just stuff the lambda into a <code>shared_ptr</code> wrapper:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> shared_lambda <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&&</span> f<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">[</span>spf <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">make_shared</span><span class="token generic class-name"><span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>decay_t<span class="token operator"><</span><span class="token keyword">decltype</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token operator">>></span></span></span><span class="token punctuation">(</span><span class="token keyword">decltype</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">]</span>
<span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&&</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>args<span class="token punctuation">)</span><span class="token operator">-></span><span class="token keyword">decltype</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token operator">*</span>spf<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">decltype</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> lamb_shared <span class="token operator">=</span> <span class="token function">shared_lambda</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">move</span><span class="token punctuation">(</span>lamb_move<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>takes our move-only lambda and stuffs its state into a shared pointer then returns a lambda that <strong>can</strong> be copied, and then stored in a <code>std::function</code> or similar.</p> <p>Generalized capture uses <code>auto</code> type deduction for the variable's type. It will declare these captures as values by default, but they can be references as well:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">auto</span> lamb <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">&</span>v <span class="token operator">=</span> a<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> add<span class="token punctuation">)</span> <span class="token comment">//Note that `a` and `v` have different names</span>
<span class="token punctuation">{</span>
v <span class="token operator">+=</span> add<span class="token punctuation">;</span> <span class="token comment">//Modifies `a`</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token function">lamb</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//`a` becomes 20.</span>
</code></pre></div><p>Generalize capture does not need to capture an external variable at all. It can capture an arbitrary expression:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> lamb <span class="token operator">=</span> <span class="token punctuation">[</span>p <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">make_unique</span><span class="token generic class-name"><span class="token operator"><</span>T<span class="token operator">></span></span></span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
p<span class="token operator">-></span><span class="token function">SomeFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>This is useful for giving lambdas arbitrary values that they can hold and potentially modify, without having to declare them externally to the lambda. Of course, that is only useful if you do not intend to access those variables after the lambda has completed its work.</p> <h2 id="conversion-to-function-pointer"><a href="#conversion-to-function-pointer" class="header-anchor">#</a> Conversion to function pointer</h2> <p>If a lambda's capture list is empty, then the lambda has an implicit conversion to a function pointer that takes the same arguments and returns the same return type:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> sorter <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> lhs<span class="token punctuation">,</span> <span class="token keyword">int</span> rhs<span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token keyword">bool</span> <span class="token punctuation">{</span><span class="token keyword">return</span> lhs <span class="token operator"><</span> rhs<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">using</span> func_ptr <span class="token operator">=</span> <span class="token keyword">bool</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
func_ptr sorter_func <span class="token operator">=</span> sorter<span class="token punctuation">;</span> <span class="token comment">// implicit conversion</span>
</code></pre></div><p>Such a conversion may also be enforced using unary plus operator:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code>func_ptr sorter_func2 <span class="token operator">=</span> <span class="token operator">+</span>sorter<span class="token punctuation">;</span> <span class="token comment">// enforce implicit conversion</span>
</code></pre></div><p>Calling this function pointer behaves exactly like invoking <code>operator()</code> on the lambda. This function pointer is in no way reliant on the source lambda closure's existence. It therefore may outlive the lambda closure.</p> <p>This feature is mainly useful for using lambdas with APIs that deal in function pointers, rather than C++ function objects.</p> <p>Conversion to a function pointer is also possible for generic lambdas with an empty capture list. If necessary, template argument deduction will be used to select the correct specialization.</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">auto</span> sorter <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span> lhs<span class="token punctuation">,</span> <span class="token keyword">auto</span> rhs<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> lhs <span class="token operator"><</span> rhs<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">using</span> func_ptr <span class="token operator">=</span> <span class="token keyword">bool</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
func_ptr sorter_func <span class="token operator">=</span> sorter<span class="token punctuation">;</span> <span class="token comment">// deduces int, int</span>
<span class="token comment">// note however that the following is ambiguous</span>
<span class="token comment">// func_ptr sorter_func2 = +sorter;</span>
</code></pre></div><h2 id="using-lambdas-for-inline-parameter-pack-unpacking"><a href="#using-lambdas-for-inline-parameter-pack-unpacking" class="header-anchor">#</a> Using lambdas for inline parameter pack unpacking</h2> <p>Parameter pack unpacking traditionally requires writing a helper function for each time you want to do it.</p> <p>In this toy example:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">template</span><span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>size_t<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>Is<span class="token operator">></span>
<span class="token keyword">void</span> <span class="token function">print_indexes</span><span class="token punctuation">(</span> std<span class="token double-colon punctuation">::</span>index_sequence<span class="token operator"><</span>Is<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">using</span> discard<span class="token operator">=</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>discard<span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">(</span>
std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> Is <span class="token operator"><<</span> <span class="token string">'\n'</span> <span class="token comment">// here Is is a compile-time constant.</span>
<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">template</span><span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>size_t I<span class="token operator">></span>
<span class="token keyword">void</span> <span class="token function">print_indexes_upto</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token function">print_indexes</span><span class="token punctuation">(</span> std<span class="token double-colon punctuation">::</span>make_index_sequence<span class="token operator"><</span>I<span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>The <code>print_indexes_upto</code> wants to create and unpack a parameter pack of indexes. In order to do so, it must call a helper function. Every time you want to unpack a parameter pack you created, you end up having to create a custom helper function to do it.</p> <p>This can be avoided with lambdas.</p> <p>You can unpack parameter packs into a set of invocations of a lambda, like this:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">template</span><span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>size_t I<span class="token operator">></span>
<span class="token keyword">using</span> index_t <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>integral_constant<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>size_t<span class="token punctuation">,</span> I<span class="token operator">></span><span class="token punctuation">;</span>
<span class="token keyword">template</span><span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>size_t I<span class="token operator">></span>
<span class="token keyword">constexpr</span> index_t<span class="token operator"><</span>I<span class="token operator">></span> index<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">template</span><span class="token operator"><</span><span class="token keyword">class</span><span class="token operator">=</span><span class="token keyword">void</span><span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>size_t<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>Is<span class="token operator">></span>
<span class="token keyword">auto</span> <span class="token function">index_over</span><span class="token punctuation">(</span> std<span class="token double-colon punctuation">::</span>index_sequence<span class="token operator"><</span>Is<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&&</span> f<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">using</span> discard<span class="token operator">=</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>discard<span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">(</span>
<span class="token function">f</span><span class="token punctuation">(</span> index<span class="token operator"><</span>Is<span class="token operator">></span> <span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">template</span><span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>size_t N<span class="token operator">></span>
<span class="token keyword">auto</span> <span class="token function">index_over</span><span class="token punctuation">(</span>index_t<span class="token operator"><</span>N<span class="token operator">></span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token function">index_over</span><span class="token punctuation">(</span> std<span class="token double-colon punctuation">::</span>make_index_sequence<span class="token operator"><</span>N<span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>With fold expressions, <code>index_over()</code> can be simplified to:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">template</span><span class="token operator"><</span><span class="token keyword">class</span><span class="token operator">=</span><span class="token keyword">void</span><span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>size_t<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>Is<span class="token operator">></span>
<span class="token keyword">auto</span> <span class="token function">index_over</span><span class="token punctuation">(</span> std<span class="token double-colon punctuation">::</span>index_sequence<span class="token operator"><</span>Is<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&&</span> f<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token function">f</span><span class="token punctuation">(</span>index<span class="token operator"><</span>Is<span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Once you have done that, you can use this to replace having to manually unpack parameter packs with a second overload in other code, letting you unpack parameter packs "inline":</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">template</span><span class="token operator"><</span><span class="token keyword">class</span> <span class="token class-name">Tup</span><span class="token punctuation">,</span> <span class="token keyword">class</span> <span class="token class-name">F</span><span class="token operator">></span>
<span class="token keyword">void</span> <span class="token function">for_each_tuple_element</span><span class="token punctuation">(</span>Tup<span class="token operator">&&</span> tup<span class="token punctuation">,</span> F<span class="token operator">&&</span> f<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">using</span> T <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span>remove_reference_t<span class="token operator"><</span>Tup<span class="token operator">></span><span class="token punctuation">;</span>
<span class="token keyword">using</span> std<span class="token double-colon punctuation">::</span>tuple_size<span class="token punctuation">;</span>
<span class="token keyword">auto</span> from_zero_to_N <span class="token operator">=</span> <span class="token generic-function"><span class="token function">index_over</span><span class="token generic class-name"><span class="token operator"><</span> tuple_size<span class="token operator"><</span>T<span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token operator">></span></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">from_zero_to_N</span><span class="token punctuation">(</span>
<span class="token punctuation">[</span><span class="token operator">&</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span> i<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">using</span> std<span class="token double-colon punctuation">::</span>get<span class="token punctuation">;</span>
<span class="token function">f</span><span class="token punctuation">(</span> <span class="token generic-function"><span class="token function">get</span><span class="token generic class-name"><span class="token operator"><</span>i<span class="token operator">></span></span></span><span class="token punctuation">(</span> std<span class="token double-colon punctuation">::</span><span class="token generic-function"><span class="token function">forward</span><span class="token generic class-name"><span class="token operator"><</span>Tup<span class="token operator">></span></span></span><span class="token punctuation">(</span>tup<span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>The <code>auto i</code> passed to the lambda by the <code>index_over</code> is a <code>std::integral_constant<std::size_t, ???></code>. This has a <code>constexpr</code> conversion to <code>std::size_t</code> that does not depend on the state of <code>this</code>, so we can use it as a compile-time constant, such as when we pass it to <code>std::get<i></code> above.</p> <p>To go back to the toy example at the top, rewrite it as:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token keyword">template</span><span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>size_t I<span class="token operator">></span>
<span class="token keyword">void</span> <span class="token function">print_indexes_upto</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">index_over</span><span class="token punctuation">(</span>index<span class="token operator"><</span>I<span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">auto</span> i<span class="token punctuation">)</span><span class="token punctuation">{</span>
std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> i <span class="token operator"><<</span> <span class="token string">'\n'</span><span class="token punctuation">;</span> <span class="token comment">// here i is a compile-time constant</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>which is much shorter, and keeps logic in the code that uses it.</p> <p><a href="http://coliru.stacked-crooked.com/a/32c204301f7163c9" target="_blank" rel="noopener noreferrer">Live example<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> to play with.</p> <h2 id="porting-lambda-functions-to-c-03-using-functors"><a href="#porting-lambda-functions-to-c-03-using-functors" class="header-anchor">#</a> Porting lambda functions to C++03 using functors</h2> <p>Lambda functions in C++ are syntactic sugar that provide a very concise syntax for writing <a href="http://stackoverflow.com/documentation/c%2B%2B/1412/class-functors#t=201607221029133733631" target="_blank" rel="noopener noreferrer">functors<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>. As such, equivalent functionality can be obtained in C++03 (albeit much more verbose) by converting the lambda function into a functor:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">// Some dummy types:</span>
<span class="token keyword">struct</span> <span class="token class-name">T1</span> <span class="token punctuation">{</span><span class="token keyword">int</span> dummy<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">struct</span> <span class="token class-name">T2</span> <span class="token punctuation">{</span><span class="token keyword">int</span> dummy<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">struct</span> <span class="token class-name">R</span> <span class="token punctuation">{</span><span class="token keyword">int</span> dummy<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// Code using a lambda function (requires C++11)</span>
R <span class="token function">use_lambda</span><span class="token punctuation">(</span>T1 val<span class="token punctuation">,</span> T2 ref<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Use auto because the type of the lambda is unknown.</span>
<span class="token keyword">auto</span> lambda <span class="token operator">=</span> <span class="token punctuation">[</span>val<span class="token punctuation">,</span> <span class="token operator">&</span>ref<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> arg1<span class="token punctuation">,</span> <span class="token keyword">int</span> arg2<span class="token punctuation">)</span> <span class="token operator">-></span> R <span class="token punctuation">{</span>
<span class="token comment">/* lambda-body */</span>
<span class="token keyword">return</span> <span class="token function">R</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token function">lambda</span><span class="token punctuation">(</span><span class="token number">12</span><span class="token punctuation">,</span> <span class="token number">27</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// The functor class (valid C++03)</span>
<span class="token comment">// Similar to what the compiler generates for the lambda function.</span>
<span class="token keyword">class</span> <span class="token class-name">Functor</span> <span class="token punctuation">{</span>
<span class="token comment">// Capture list.</span>
T1 val<span class="token punctuation">;</span>
T2<span class="token operator">&</span> ref<span class="token punctuation">;</span>
<span class="token keyword">public</span><span class="token operator">:</span>
<span class="token comment">// Constructor</span>
<span class="token keyword">inline</span> <span class="token function">Functor</span><span class="token punctuation">(</span>T1 val<span class="token punctuation">,</span> T2<span class="token operator">&</span> ref<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">val</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">ref</span><span class="token punctuation">(</span>ref<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token comment">// Functor body</span>
R <span class="token keyword">operator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">int</span> arg1<span class="token punctuation">,</span> <span class="token keyword">int</span> arg2<span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span>
<span class="token comment">/* lambda-body */</span>
<span class="token keyword">return</span> <span class="token function">R</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// Equivalent to use_lambda, but uses a functor (valid C++03).</span>
R <span class="token function">use_functor</span><span class="token punctuation">(</span>T1 val<span class="token punctuation">,</span> T2 ref<span class="token punctuation">)</span> <span class="token punctuation">{</span>
Functor <span class="token function">functor</span><span class="token punctuation">(</span>val<span class="token punctuation">,</span> ref<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token function">functor</span><span class="token punctuation">(</span><span class="token number">12</span><span class="token punctuation">,</span> <span class="token number">27</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Make this a self-contained example.</span>
<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
T1 t1<span class="token punctuation">;</span>
T2 t2<span class="token punctuation">;</span>
<span class="token function">use_functor</span><span class="token punctuation">(</span>t1<span class="token punctuation">,</span>t2<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">use_lambda</span><span class="token punctuation">(</span>t1<span class="token punctuation">,</span>t2<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>If the lambda function is <code>mutable</code> then make the functor's call-operator non-const, i.e.:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code>R <span class="token keyword">operator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">int</span> arg1<span class="token punctuation">,</span> <span class="token keyword">int</span> arg2<span class="token punctuation">)</span> <span class="token comment">/*non-const*/</span> <span class="token punctuation">{</span>
<span class="token comment">/* lambda-body */</span>
<span class="token keyword">return</span> <span class="token function">R</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h4 id="syntax"><a href="#syntax" class="header-anchor">#</a> Syntax</h4> <ul><li>[<strong>default-capture</strong>, <strong>capture-list</strong>] (<strong>argument-list</strong>) mutable <strong>throw-specification</strong> <strong>attributes</strong> -> <strong>return-type</strong> { <strong>lambda-body</strong> } // Order of lambda specifiers and attributes.</li> <li>[<strong>capture-list</strong>] (<strong>argument-list</strong>) { <strong>lambda-body</strong> } // Common lambda definition.</li> <li>[=] (<strong>argument-list</strong>) { <strong>lambda-body</strong> } // Captures all needed local variables by value.</li> <li>[&] (<strong>argument-list</strong>) { <strong>lambda-body</strong> } // Captures all needed local variables by reference.</li> <li>[<strong>capture-list</strong>] { <strong>lambda-body</strong> } // Argument list and specifiers can be omitted.</li></ul> <h4 id="parameters"><a href="#parameters" class="header-anchor">#</a> Parameters</h4> <table><thead><tr><th>Parameter</th> <th>Details</th></tr></thead> <tbody><tr><td><strong>default-capture</strong></td> <td>Specifies how all non-listed variables are captured. Can be <code>=</code> (capture by value) or <code>&</code> (capture by reference). If omitted, non-listed variables are inaccessible within the <strong>lambda-body</strong>. The <strong>default-capture</strong> must precede the <strong>capture-list</strong>.</td></tr> <tr><td><strong>capture-list</strong></td> <td>Specifies how local variables are made accessible within the <strong>lambda-body</strong>. Variables without prefix are captured by value. Variables prefixed with <code>&</code> are captured by reference. Within a class method, <code>this</code> can be used to make all its members accessible by reference. Non-listed variables are inaccessible, unless the list is preceded by a <strong>default-capture</strong>.</td></tr> <tr><td><strong>argument-list</strong></td> <td>Specifies the arguments of the lambda function.</td></tr> <tr><td>mutable</td> <td><strong>(optional)</strong> Normally variables captured by value are <code>const</code>. Specifying <code>mutable</code> makes them non-const. Changes to those variables are retained between calls.</td></tr> <tr><td><strong>throw-specification</strong></td> <td><strong>(optional)</strong> Specifies the exception throwing behavior of the lambda function. For example: <code>noexcept</code> or <code>throw(std::exception)</code>.</td></tr> <tr><td><strong>attributes</strong></td> <td><strong>(optional)</strong> Any attributes for the lambda function. For example, if the <strong>lambda-body</strong> always throws an exception then <code>[[noreturn]]</code> can be used.</td></tr> <tr><td>-> <strong>return-type</strong></td> <td><strong>(optional)</strong> Specifies the return type of the lambda function. Required when the return type cannot be determined by the compiler.</td></tr> <tr><td><strong>lambda-body</strong></td> <td>A code block containing the implementation of the lambda function.</td></tr></tbody></table> <h4 id="remarks"><a href="#remarks" class="header-anchor">#</a> Remarks</h4> <p>C++17 (the current draft) introduces <code>constexpr</code> lambdas, basically lambdas that can be evaluated at compile time. A lambda is automatically <code>constexpr</code> if it satisfies <code>constexpr</code> requirements, but you can also specify it using the <code>constexpr</code> keyword:</p> <div class="language-cpp extra-class"><pre class="language-cpp"><code><span class="token comment">//Explicitly define this lambdas as constexpr</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">constexpr</span> <span class="token punctuation">{</span>
<span class="token comment">//Do stuff</span>
<span class="token punctuation">}</span>
</code></pre></div></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/devtut/generate/edit/master/docs/cpp/lambdas.md" target="_blank" rel="noopener noreferrer">Edit this page on GitHub</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
←
<a href="/cpp/exceptions.html" class="prev">
Exceptions
</a></span> <span class="next"><a href="/cpp/value-categories.html">
Value Categories
</a>
→
</span></p></div> </main></div><div class="global-ui"><!----></div></div>
<script src="/assets/js/app.1779e102.js" defer></script><script src="/assets/js/3.2cfa8016.js" defer></script><script src="/assets/js/669.4e6cb383.js" defer></script>
</body>
</html>