Is there a way to overload, say the >> operator for function composition? The operator should work seamlessly on lambdas as well as std::function?
Requirements:
- The solution should not include nested
bindcalls, - the left operand can be of a functional type with an arbitrary number of parameters, and
- no more than one function object instance should be created.
Here is a quick and dirty example that illustrates the desired behaviour:
#include <iostream>
#include <functional>
using namespace std;
// An example of a quick and dirty function composition.
// Note that instead of 'std::function' this operator should accept
// any functional/callable type (just like 'bind').
template<typename R1, typename R2, typename... ArgTypes1>
function<R2(ArgTypes1...)> operator >> (
const function<R1(ArgTypes1...)>& f1,
const function<R2(R1)>& f2) {
return [=](ArgTypes1... args){ return f2(f1(args...)); };
}
int main(int argc, char **args) {
auto l1 = [](int i, int j) {return i + j;};
auto l2 = [](int i) {return i * i;};
function<int(int, int)> f1 = l1;
function<int(int)> f2 = l2;
cout << "Function composition: " << (f1 >> f2)(3, 5) << endl;
// The following is desired, but it doesn't compile as it is:
cout << "Function composition: " << (l1 >> l2)(3, 5) << endl;
return 0;
}
(l1 >> l2)can never work.They are function objects made by the compiler and don’t include that operator, so unless you plan on modifying the compiler to be non-conforming that’s how it’s always going to be. 🙂
You can, however, introduce a “keyword” (utility class) which is arguably a good thing, but it’s hefty:
That’s a quite a bit of code! Unfortunately I don’t see how it can be reduced any.
You can go another route and just make it so to use lambdas in your scheme, you just have to explicitly make them
std::function<>s, but it’s less uniform. Some of the machinery above could be used to make some sort ofto_function()function for making lambda functions intostd::function<>s.