How it works...

Composing two unary functions into a new one is relatively trivial. Create a template function that we called compose() in the earlier examples, with two arguments--f and g--that represent functions, and return a function that takes one argument x and returns f(g(x)). It is important though that the type of the value returned by the g function is the same as the type of the argument of the f function. The returned value of the compose function is a closure, that is, an instantiation of a lambda.

In practice, it is useful to be able to combine more than just two functions together. This can be achieved by writing a variadic template version of the compose() function. Variadic templates are explained in more detail in the Writing a function template with a variable number of arguments recipe. Variadic templates imply compile-time recursion by expanding the parameter pack. This implementation is very similar to the first version of compose(), except as follows:

  • It takes a variable number of functions as arguments.
  • The returned closure calls compose() recursively with the expanded parameter pack; recursion ends when only two functions are left, in which case, the previously implemented overload is called.
Even if the code looks like recursion is happening, this is not true recursion. It could be called compile-time recursion, but with every expansion, we get a call to another method with the same name but a different number of arguments, which does not represent recursion.

Now that we have these variadic template overloads implemented, we can rewrite the last example from the previous recipe, Implementing higher-order functions map and fold. Having an initial vector of integers, we map it to a new vector with only positive values by applying std::abs() on each element. The result is then mapped to a new vector by doubling the value of each element. Finally, the values in the resulting vector are folded together by adding them to the initial value 0:

    auto s = compose( 
[](std::vector<int> const & v) {
return foldl(std::plus<>(), v, 0); },
[](std::vector<int> const & v) {
return mapf([](int const i) {return i + i; }, v); },
[](std::vector<int> const & v) {
return mapf([](int const i) {return std::abs(i); }, v); })(vnums);
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset