#include <iostream>
#include <functional>
#include <cmath>
template <typename Result, typename Arg>
class Function
{
public:
Function(const std::function<Result(Arg)> & f) : f_(f) {}
Result operator() (Arg arg) const { return f_(arg); }
Function compose(const Function& g) const
{
return { [this, g](Arg arg) { return f_(g(arg)); } };
}
private:
std::function<Result(Arg)> f_;
};
int main()
{
auto f = Function<double, double>([](double x) { return exp(x); });
auto g = Function<double, double>([](double x) { return pow(x, 2); });
auto h = Function<double, double>([](double x) { return -x + 1; });
auto c = f.compose(g).compose(h);
std::cout << c(3.0) << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPGNtYXRoPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFJlc3VsdCwgdHlwZW5hbWUgQXJnPgpjbGFzcyBGdW5jdGlvbgp7CnB1YmxpYzoKICAgICAgICBGdW5jdGlvbihjb25zdCBzdGQ6OmZ1bmN0aW9uPFJlc3VsdChBcmcpPiAmIGYpIDogZl8oZikge30KCiAgICAgICAgUmVzdWx0IG9wZXJhdG9yKCkgKEFyZyBhcmcpIGNvbnN0IHsgcmV0dXJuIGZfKGFyZyk7IH0KCiAgICAgICAgRnVuY3Rpb24gY29tcG9zZShjb25zdCBGdW5jdGlvbiYgZykgY29uc3QKICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4geyBbdGhpcywgZ10oQXJnIGFyZykgeyByZXR1cm4gZl8oZyhhcmcpKTsgfSB9OwogICAgICAgIH0KCnByaXZhdGU6CiAgICAgICAgc3RkOjpmdW5jdGlvbjxSZXN1bHQoQXJnKT4gZl87Cn07CgppbnQgbWFpbigpCnsKICAgICAgICBhdXRvIGYgPSBGdW5jdGlvbjxkb3VibGUsIGRvdWJsZT4oW10oZG91YmxlIHgpIHsgcmV0dXJuIGV4cCh4KTsgfSk7CiAgICAgICAgYXV0byBnID0gRnVuY3Rpb248ZG91YmxlLCBkb3VibGU+KFtdKGRvdWJsZSB4KSB7IHJldHVybiBwb3coeCwgMik7IH0pOwogICAgICAgIGF1dG8gaCA9IEZ1bmN0aW9uPGRvdWJsZSwgZG91YmxlPihbXShkb3VibGUgeCkgeyByZXR1cm4gLXggKyAxOyB9KTsKICAgICAgICBhdXRvIGMgPSBmLmNvbXBvc2UoZykuY29tcG9zZShoKTsKICAgICAgICBzdGQ6OmNvdXQgPDwgYygzLjApIDw8IHN0ZDo6ZW5kbDsKCiAgICAgICAgcmV0dXJuIDA7Cn0=
prog.cpp: In lambda function:
prog.cpp:15:54: error: invalid type argument
In file included from prog.cpp:2:0:
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/functional: In static member function 'static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = double, _Functor = Function<Result, Arg>::compose(const Function<Result, Arg>&) const [with Result = double, Arg = double, Function<Result, Arg> = Function<double, double>]::<lambda(double)>, _ArgTypes = {double}]':
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/functional:2103:6: instantiated from 'std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = Function<Result, Arg>::compose(const Function<Result, Arg>&) const [with Result = double, Arg = double, Function<Result, Arg> = Function<double, double>]::<lambda(double)>, _Res = double, _ArgTypes = {double}, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<double(double)>::_Useless]'
prog.cpp:15:68: instantiated from 'Function<Result, Arg> Function<Result, Arg>::compose(const Function<Result, Arg>&) const [with Result = double, Arg = double, Function<Result, Arg> = Function<double, double>]'
prog.cpp:27:29: instantiated from here
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/functional:1699:47: error: void value not ignored as it ought to be
prog.cpp: In lambda function:
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/functional:1699:47: instantiated from 'static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = double, _Functor = Function<Result, Arg>::compose(const Function<Result, Arg>&) const [with Result = double, Arg = double, Function<Result, Arg> = Function<double, double>]::<lambda(double)>, _ArgTypes = {double}]'
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/functional:2103:6: instantiated from 'std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = Function<Result, Arg>::compose(const Function<Result, Arg>&) const [with Result = double, Arg = double, Function<Result, Arg> = Function<double, double>]::<lambda(double)>, _Res = double, _ArgTypes = {double}, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<double(double)>::_Useless]'
prog.cpp:15:68: instantiated from 'Function<Result, Arg> Function<Result, Arg>::compose(const Function<Result, Arg>&) const [with Result = double, Arg = double, Function<Result, Arg> = Function<double, double>]'
prog.cpp:27:29: instantiated from here
prog.cpp:15:66: error: return-statement with a value, in function returning 'void'