DEV Community

Cover image for How to inherit from lambdas?
Elvis Oric
Elvis Oric

Posted on • Updated on

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

Discussion (0)