Skip to content

Latest commit

 

History

History
131 lines (96 loc) · 3.19 KB

README.md

File metadata and controls

131 lines (96 loc) · 3.19 KB

Contents

  1. Allow lambda capture [=, this]
  2. Templated lambda expression
  3. Perfect forwarding
  4. Allow pack expansion in lambda init-capture
  5. Lambdas (without captures) are default-constructiable and assignable
  6. Lambdas in unevaluated contexts

⬅️ Back to Contents

Allow lambda capture [=, this]

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)

⬆️ Back to Contents

Templated lambda expression

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) {
  // ...
};

⬆️ Back to Contents

Perfect forwarding

// 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)...);
};

⬆️ Back to Contents

Allow pack expansion in lambda init-capture

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...);
  };
}

⬆️ Back to Contents

Lambdas (without captures) are default-constructiable and assignable

TODO:

⬆️ Back to Contents

Lambdas in unevaluated contexts

  • 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;

⬆️ Back to Contents