Search code examples
c++11lambdafunctional-programmingfunction-composition

Is it possible in C++11 to combine functions into a new function?


This is more a kind of theoretical question. Is it possible in C++11 to combine functions into a new function? For example :

auto f = [](int i){return i * 2;};
auto g = [](int i){return i + 10;};

So this works:

auto c = f(g(20)); // = 60

But I want an object that stores the combination, like

auto c = f(g);
std::cout << c(20) << std::endl; //prints 60

Edit: Additionally what i want to create is a function a, which you can give a function b and an int n, and which returns the n'th combination of the given function b. For example (not compilable)

template<typename T>
auto combine(T b, int i) -> decltype(T)
{
   if (i == 0)
      return b;

   return combine(b, i - 1);      
}

auto c = combine(f, 2); //c = f(f(f(int)))

Solution

  • You can write something along the lines of:

    #include <functional>
    #include <iostream>
    
    template<class F>
    F compose(F f, F g)
    {
      return [=](int x) { return f(g(x)); };
    }
    
    int main()
    {
      std::function<int (int)> f = [](int i) { return i * 2; };
      std::function<int (int)> g = [](int i) { return i + 10; };
    
      auto c = compose(f, g);
      std::cout << c(20) << '\n';  // prints 60
    }
    

    The code can be simply extended to cover the second half of the question:

    template<class F>
    F compose(F f, unsigned n)
    {
      auto g = f;
    
      for (unsigned i = 0; i < n; ++i)
        g = compose(g, f);
    
      return g;
    }
    
    int main()
    {
      std::function<int (int)> h = [](int i) { return i * i; };
    
      auto d = compose(h, 1);
      auto e = compose(h, 2);
      std::cout << d(3) << "\n"    // prints 81
                << e(3) << "\n";   // prints 6561
    }
    

    NOTE. Here using std::function. It isn't a lambda but wraps a lambda with a performance cost.