Search code examples
c++lambdatypesreturn-typehigher-order-functions

C++: implementing a higher-order function which receives a lambda as an input


Let's take a look at the following function:

auto F(vector <int> *p) {
  return [p](int y) -> int{ return y + (*p)[0]; };
}

It does a pretty simple thing: it receives a pointer at a vector of integers and returns a lambda which has another integer as an input and returns the result of adding this integer to the first element of the vector we have a pointer at. If I want to implement a higher-order function which could accept such a lambda as input, I, obviously, cannot use the auto in the prototype. I tried fixing it like this:

typedef int *A (int);

A F(vector <int> *p) {
      return [p](int y) -> int{ return y + (*p)[0]; };
    }

But that implementation brings about a conflict as well: the lambda type cannot be converted to A.

How could this be implemented?


Solution

  • I tried fixing it like this:

    typedef int *A (int);
    
    A F(vector <int> *p) {
          return [p](int y) -> int{ return y + (*p)[0]; };
    }
    

    ... the lambda type cannot be converted to A.

    This would make sense in principle only for a completely stateless lambda. Your lambda has a capture, which means it has state that needs to be stored somewhere, which means it must be a callable object rather than a simple free function.

    Your options are:

    1. Implement the higher-order function as a template on the lower-order type:

      template <typename Func>
      int higherOrder(int x, Func&& f)
      {
        return f(x);
      }
      

      or

    2. Wrap the lambda inside something with a well-known type, usually

      int higherOrder(int x, std::function<int(int)> const &f)
      {
        return f(x);
      }