DEV Community

Cover image for How to inherit from lambdas?
rndthts.dev
rndthts.dev

Posted on • Edited on • Originally published at rndthts.dev

10 4 1

How to inherit from lambdas?

What happens behind the scene when lambda is created:

auto fun = [](int num) { return num; };
Enter fullscreen mode Exit fullscreen mode

C++ Insights can be used to see what is going on behind the scene:

class __lambda_1_12
{
  public: 
  inline /*constexpr */ int operator()(int num) const
  {
    return num;
  }

  using retType_1_12 = int (*)(int);
  inline /*constexpr */ operator retType_1_12 () const noexcept
  {
    return __invoke;
  };

  private: 
  static inline int __invoke(int num)
  {
    return num;
  }
};

__lambda_1_12 fun = __lambda_1_12{};
Enter fullscreen mode Exit fullscreen mode

This tells us that lambdas are standard types, and that actually we can inherit from them.

template <typename L1, typename L2>
struct Combo : L1, L2 {
    Combo(L1 l1, L2 l2) : L1(std::move(l1)), L2(std::move(l2)) {}
    using L1::operator();
    using L2::operator();
}
Enter fullscreen mode Exit fullscreen mode

Let's create two lambdas:

auto l1 = []{return 42;};
auto l2 = [](const int n){ return n*n;}
Enter fullscreen mode Exit fullscreen mode

When instantiating Combo we will take advantage of Class Template Argument Deduction from C++17

 Combo combo(l1, l2);
 std::cout << combo() << std::endl;
 std::cout << combo(3) << std::endl;
Enter fullscreen mode Exit fullscreen mode

A more generic version can be created and used as

struct Combo : Ls... {
    Combo(Ls... ls) : Ls(std::move(ls))... {}
    using Ls::operator()...;
}
Enter fullscreen mode Exit fullscreen mode
    auto l1 = [] { return 42; };
    auto l2 = [](const int n) { return n * n; };
    auto l3 = [](const int n, int m) { return n * m; };

    Combo combo(l1, l2, l3, [](const std::string& s){return s + " " + s;});
    std::cout << combo() << std::endl;
    std::cout << combo(3) << std::endl;
    std::cout << combo(3, 43) << std::endl;
    std::cout << combo("cpp") << std::endl;

Enter fullscreen mode Exit fullscreen mode

First version:
https://godbolt.org/z/TWs3e8raY

Second version:
https://godbolt.org/z/7qvchhvzx

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay