What happens behind the scene when lambda is created:
auto fun = [](int num) { return num; };
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{};
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();
}
Let's create two lambdas:
auto l1 = []{return 42;};
auto l2 = [](const int n){ return n*n;}
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;
A more generic version can be created and used as
struct Combo : Ls... {
    Combo(Ls... ls) : Ls(std::move(ls))... {}
    using Ls::operator()...;
}
    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;
First version:
https://godbolt.org/z/TWs3e8raY
Second version:
https://godbolt.org/z/7qvchhvzx
 
 
              
 
    
Top comments (0)