- Allow lambda capture
[=, this]
- Templated lambda expression
- Perfect forwarding
- Allow pack expansion in lambda init-capture
- Lambdas (without captures) are default-constructiable and assignable
- Lambdas in unevaluated contexts
Since C++20, you need to capture this
explicitly in case of using [=]
, e.g.
[=]
->[=, this]
- local variables by value, class members by reference[=]
->[=, *this]
- everything by value[&]
->[&, this]
- everything by reference[&]
->[&, *this]
- (this would be unusual)
Added possibility to use templated lambda expressions, e.g. []<typename T>(T t) { /* ... */ }
- Retrieve type of parameters of generic lambdas to access static members/methods or nested aliases
// Before
auto foo = [](const auto& value) {
using T = std::decay_t<decltype(value)>;
T valueCopy = value;
T::staticMethod();
using Alias = T::NestedAlias;
};
// Now
auto foo = []<typename T>(const T& value) {
T valueCopy = value;
T::staticMethod();
using Alias = T::NestedAlias;
};
- Retrieve type of the element of containers
// Before
auto foo = [](const auto& data) {
using T = typename std::decay_t<decltype(data)>::value_type;
// ...
};
// Now
auto foo = []<typename T>(const std::vector<T>& data) {
// ...
};
// Before
auto foo = [](auto&&... args) {
return bar(std::forward<decltype(args)>(args)...);
};
// Now
auto foo = []<typename ...T>(T&&... args) {
return bar(std::forward<T>(args)...);
};
template<typename F, typename... Args>
auto DelayInvoke(F f, Args... args) {
return [f = std::move(f), args = std::move(args)...]() { // ...args?
return std::invoke(f, args...);
};
}
TODO:
- Lambda as a member of a class
class Widget {
decltype([]{}) foo;
};
- Custom deleter for smart pointers
template<typename T>
using MyPtr = std::unique_ptr<T, decltype([](T* t) { MyDeleter(t); })>
MyPtr<Widget> ptr;
- Predicate for containers
using WidgetSet = std::set<Widget, decltype([](Widget& lhs, Widget& rhs) { return lhs.x < rhs.x; } )>
WidgetSet widgets;