### Lambdas are not function objects

Lambdas (or lambda expressions) in C++11 are a blessing for C++ programmers that have been exposed to functional programming. And, in conjunction with the extended capabilities of templates, they can bring the abstraction level of software to a whole new level. Yet, as often in C++, language features aren’t driven only by expressiveness and generalisation, and we’re left with some minuscule stones in our shoes that end up ruining the whole walk.

My intolerable aggravation here is that lambdas are not function objects, i.e. `std::function<R (Args...)>`

as defined by standard library header `functional`

. And this is a problem because the way function objects are templated makes it very easy to meta-program with them. Whereas lambdas are almost opaque. It would be perfectly OK for me to automatically convert lambdas to function objects all the time, since when i’m coding at this level of abstractness, efficiency is very far from being an important consideration. But, alas, i know of no such feature in the language or standard library.

### So what?

So if only i had something like

template <typename LambdaT> function<typename LambdaT::signature> to_function(LambdaT lambda);

then, every time i have a function that has an STL `function`

argument, like for instance

// vectorize function object template <typename R, typename... A> function<vector<R> (vector<A>...)> vectorize(function<R (A...)> f);

i would nonchalantly tack on

// vectorize a lambda template <typename LambdaT> auto vectorize(LambdaT f) -> decltype(vectorize(to_function(f))) { return vectorize(to_function(f)); }

and relax. The first version of my function would do all the type deducing; the second would deal with the very common case of using a lambda expression instead of a function object.

### Why would you want to do that anyway?

Because functional programming is powerful. Using functional programming, some problems can be structured into simple functions and function manipulations (function functions, operations with functions, function transformations…), which really, *really*, reduces the amount of code, and allows for a deeper understanding and structuring of the problem, one that will have more of the good features we want our code to have (clearness, correctness, testability, maintainability, reusability).

### Allrighty, but what would you do with that?

The example above solves a basic functional problem: given a function object `f`

that has some arguments and returns a result, how can i get the equivalent function that does the same with matching elements of `std::vector`

arguments and returns a `std::vector`

of results? Specifically, i would like the expression `vectorize(f)`

to return a function, let’s call it `vf`

, such that the pseudo-expression

vf(vector{a1, a2, ...}, vector{b1, b2, ...}, ...)

returns the same value as

vector{f(a1, b1, ...), f(a2, b2, ...), ...}

This is how it’s done:

template <typename R, typename... A> function<vector<R> (vector<A>...)> vectorize(function<R (A...)> f) { return [f](vector<A> &&...la) { vector<R> result; for (size_t i=0; i<common_size(la...); ++i) result.push_back(f(la[i]...)); return result; }; }

Using the explicit templatisation of the `function<R (A...)>`

argument, we deduce its return and argument types, of which there can be any number thanks to the variadic template, and then, judiciously sprinkling our code with trios of periods, we can turn our variadic deductions into general recipes to achieve our goal.

The only thing that remains to be done in the code above is to define the function `common_size()`

, which returns the common size of its vector arguments or, if they are not all the same size, just throws an exception (a plain string here, to keep it simple):

// handle single argument template <typename Arg> size_t common_size(Arg &&a) { return a.size(); } // recursively handle more than one argument template <typename Arg, typename... Rest> size_t common_size(Arg &&a, Rest &&... rest) { if (a.size()==common_size(rest...)) return a.size(); else throw "unequal sizes"; }

Here’s a simple example of usage for `vectorize()`

:

auto div=[](int x, float y) { return x/y; }; vector<int> a{1, 2, 3}; vector<float> b{2., 4., 5.}; auto r=vectorize(div)(a, b);

which should give `r`

the value

vector<float>{0.5 0.5 0.6}

… except it doesn’t cus it doesn’t even compile. Because “Lambdas are not function objects”. Instead, we have to use this unwonderful, over-explicit syntax, where we tell the compiler things *he* already knows, but somehow can’t put to use by *himself* (i resort to anthropomorphisation to relieve my frustration):

auto r=vectorize(function<float (int, float)>(div))(a, b);

### There’s a way

Yes, there’s a way to keep the first wonderful, terse syntax, if we code the second version of `vectorize()`

, the one for lambdas, that converts to `function`

and delegates to the first version. We just need to write `to_function()`

.

And there’s a way to write `to_function()`

, because lambdas are not so opaque after all.

The type of a lambda is compiler-dependent, but it must comply with this requirement: it must have an `operator()()`

(a *function call operator* if you’re reading aloud), matching its signature, of course. And although you can’t directly access its signature, you can get its type (as a method pointer) using the `decltype`

specifier. If you have a lambda with type `LambdaT`

, the type of its `operator()()`

is given by

decltype(&LambdaT::operator())

and it’s something you can match in a template with the generic type

Ret (Obj::*)(Args...)

where `Ret`

, `Obj`

, and `Args...`

are template arguments, used to deduce the signature with a level of indirection.

So, if you have the type of a lambda (or, for that matter, any other object that supports `operator()()`

, as should be clear by now), you can deduce its signature and produce the type of the equivalent `function`

object like this (the definitions are out of order to aid the exposition):

template <typename LambdaT> struct as_function : public method_as_function<decltype(&LambdaT::operator())> { }; template <typename T> struct method_as_function; template <typename Obj, typename Ret, typename... Args> struct method_as_function<Ret (Obj::*)(Args...) const> { type=std::function<Ret (Args...)>; };

And using these definitions, `to_function()`

is simple and beautiful:

template <typename F> typename as_function<F>::type to_function(F &&f) { return f; }

So that’s the heart of the technique i wanted to demonstrate. Put the definitions in the right order, add some bells and whistles, and you have a small library to convert lambdas and other function-like objects into `function`

objects, for easy functional meta-programming.

### The code and the test

So here’s a small complete header that implements the ideas explained above, with some extra features like handling raw function pointers, references to lambda objects, and a `_t<>`

companion to `as_function<>`

, à la C++14 STL.

And here’s a test:

The test should print the following: