#include <functional>
template<class Callable1, class Callable2>
struct Chain : public std::unary_function<
typename Callable2::argument_type,
typename Callable1::result_type>
{
Chain(const Callable1 &f1, const Callable2 &f2) : f1(f1), f2(f2) {}
typename Callable1::result_type operator () (typename Callable2::argument_type param) { return f1(f2(param)); }
private:
Callable1 f1;
Callable2 f2;
};
template<class Callable1, class Callable2>
Chain<Callable1, Callable2> chain(const Callable1 &f1, const Callable2 &f2) {
return Chain<Callable1, Callable2>(f1, f2);
}
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
struct foo : public unary_function<int, double> {
double m;
foo(double m) : m(m) {}
double operator() (int x) { return m + x; }
};
struct bar : public unary_function<double, string> {
string operator() (double y) {
stringstream ss;
ss << y;
return ss.str();
}
};
int main() {
cout << foo(0.4)(5) << endl;
cout << bar()(4.5) << endl;
cout << chain(bar(), foo(3.4))(7) << endl;
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+Cgp0ZW1wbGF0ZTxjbGFzcyBDYWxsYWJsZTEsIGNsYXNzIENhbGxhYmxlMj4Kc3RydWN0IENoYWluIDogcHVibGljIHN0ZDo6dW5hcnlfZnVuY3Rpb248CiAgICB0eXBlbmFtZSBDYWxsYWJsZTI6OmFyZ3VtZW50X3R5cGUsIAogICAgdHlwZW5hbWUgQ2FsbGFibGUxOjpyZXN1bHRfdHlwZT4KewogICAgQ2hhaW4oY29uc3QgQ2FsbGFibGUxICZmMSwgY29uc3QgQ2FsbGFibGUyICZmMikgOiBmMShmMSksIGYyKGYyKSB7fQogICAgCiAgICB0eXBlbmFtZSBDYWxsYWJsZTE6OnJlc3VsdF90eXBlIG9wZXJhdG9yICgpICh0eXBlbmFtZSBDYWxsYWJsZTI6OmFyZ3VtZW50X3R5cGUgcGFyYW0pIHsgcmV0dXJuIGYxKGYyKHBhcmFtKSk7IH0KcHJpdmF0ZToKICAgIENhbGxhYmxlMSBmMTsKICAgIENhbGxhYmxlMiBmMjsKfTsKCnRlbXBsYXRlPGNsYXNzIENhbGxhYmxlMSwgY2xhc3MgQ2FsbGFibGUyPgpDaGFpbjxDYWxsYWJsZTEsIENhbGxhYmxlMj4gY2hhaW4oY29uc3QgQ2FsbGFibGUxICZmMSwgY29uc3QgQ2FsbGFibGUyICZmMikgewogICAgcmV0dXJuIENoYWluPENhbGxhYmxlMSwgQ2FsbGFibGUyPihmMSwgZjIpOwp9CgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzc3RyZWFtPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cnVjdCBmb28gOiBwdWJsaWMgdW5hcnlfZnVuY3Rpb248aW50LCBkb3VibGU+IHsKICAgIGRvdWJsZSBtOwogICAgZm9vKGRvdWJsZSBtKSA6IG0obSkge30KICAgIGRvdWJsZSBvcGVyYXRvcigpIChpbnQgeCkgeyByZXR1cm4gbSArIHg7IH0KfTsKCnN0cnVjdCBiYXIgOiBwdWJsaWMgdW5hcnlfZnVuY3Rpb248ZG91YmxlLCBzdHJpbmc+IHsKICAgIHN0cmluZyBvcGVyYXRvcigpIChkb3VibGUgeSkgewogICAgICAgIHN0cmluZ3N0cmVhbSBzczsKICAgICAgICBzcyA8PCB5OwogICAgICAgIHJldHVybiBzcy5zdHIoKTsKICAgIH0KfTsKCmludCBtYWluKCkgewogICAgY291dCA8PCBmb28oMC40KSg1KSA8PCBlbmRsOwogICAgY291dCA8PCBiYXIoKSg0LjUpIDw8IGVuZGw7CiAgICAKICAgIGNvdXQgPDwgY2hhaW4oYmFyKCksIGZvbygzLjQpKSg3KSA8PCBlbmRsOwp9Cg==