mirror of
https://github.com/AnthonyCalandra/modern-cpp-features.git
synced 2025-12-17 10:04:35 +03:00
Add C++14 initializiers for lambda captures
This commit is contained in:
30
README.md
30
README.md
@@ -27,6 +27,7 @@ C++17 includes the following new library features:
|
||||
C++14 includes the following new language features:
|
||||
- [binary literals](#binary-literals)
|
||||
- [generic lambda expressions](#generic-lambda-expressions)
|
||||
- [lambda capture initializers](#lambda-capture-initializers)
|
||||
- [return type deduction](#return-type-deduction)
|
||||
- [decltype(auto)](#decltypeauto)
|
||||
- [relaxing constraints on constexpr functions](#relaxing-constraints-on-constexpr-functions)
|
||||
@@ -385,6 +386,35 @@ int three = identity(3); // == 3
|
||||
std::string foo = identity("foo"); // == "foo"
|
||||
```
|
||||
|
||||
### Lambda capture initializers
|
||||
This allows creating lambda captures initialized with arbitrary expressions. The name given to the captured value does not need to be related to any variables in the enclosing scopes and introduces a new name inside the lambda body. The initializing expression is evaluated when the lambda is _created_ (not when it is _invoked_).
|
||||
```c++
|
||||
int factory(int i) { return i * 10; }
|
||||
auto f = [x = factory(2)] { return x; }; // returns 20
|
||||
|
||||
auto generator = [x = 0] () mutable { return x++; };
|
||||
auto a = generator(); // a = 0
|
||||
auto b = generator(); // b = 1
|
||||
```
|
||||
Because it is now possible to _move_ (or _forward_) values into a lambda that could previously be only captured by copy or reference we can now capture move-only types in a lambda by value. Note that in the below example the `p` in the capture-list of `task2` on the left-hand-side of `=` is a new variable private to the lambda body and does not refer to the original `p`.
|
||||
```c++
|
||||
auto p = std::make_unique<int>(1);
|
||||
|
||||
auto task1 = [=] { return *p = 5; } // ERROR: std::unique_ptr cannot be copied
|
||||
// vs.
|
||||
auto task2 = [p = std::move(p)] { *p = 5; }; // OK: p is move-constructed into the closure object
|
||||
// the original p is empty after task2 is created
|
||||
```
|
||||
Using this reference-captures can have different names than the referenced variable.
|
||||
```c++
|
||||
auto x = 1;
|
||||
auto f = [&r = x, x = x * 10] {
|
||||
++r;
|
||||
return r + x;
|
||||
};
|
||||
f(); // sets x to 2 and returns 12
|
||||
```
|
||||
|
||||
### Return type deduction
|
||||
Using an `auto` return type in C++14, the compiler will attempt to deduce the type for you. With lambdas, you can now deduce its return type using `auto`, which makes returning a deduced reference or rvalue reference possible.
|
||||
```c++
|
||||
|
||||
Reference in New Issue
Block a user