g++ -std=c++11 main.cc
./a.out
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Erasure
#include <cstdio> | |
// From http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Erasure | |
template <class A, class B> | |
class Function { | |
private: | |
struct Interface { | |
virtual ~Interface() { } | |
virtual Interface *clone() const = 0; | |
virtual B call(A) const = 0; | |
}; | |
template<class F> | |
struct Model : Interface { | |
explicit Model(F const &data) : data(data) { } | |
virtual Model *clone() const { return new Model(data); } | |
virtual B call(A arg) const { | |
return data(arg); | |
} | |
F data; | |
}; | |
Interface *iface; | |
public: | |
template <class F> | |
explicit Function(F const &data) : iface(new Model<F>(data)) { } | |
Function(Function const &that) | |
: iface(that.iface ? that.iface->clone() : NULL) { } | |
~Function() { | |
delete iface; | |
} | |
B operator()(A arg) const { | |
return iface->call(arg); | |
} | |
}; | |
int main() { | |
typedef Function<long, long> F_l_l; | |
Function<long, F_l_l> add( | |
[=](long lhs) -> F_l_l { | |
return F_l_l( | |
[=](long rhs) -> long { | |
return lhs + rhs; | |
}); | |
}); | |
Function<F_l_l, Function<F_l_l, F_l_l> > compose( | |
[=](F_l_l f) -> Function<F_l_l, F_l_l> { | |
return Function<F_l_l, F_l_l>( | |
[=](F_l_l g) -> F_l_l { | |
return F_l_l([=](long arg) -> long { | |
return f(g(arg)); | |
}); | |
}); | |
}); | |
Function<F_l_l, F_l_l> twice( | |
[=](F_l_l f) -> F_l_l { | |
return compose(f)(f); | |
}); | |
Function<long, long> addOne(add(1)); | |
Function<long, long> addTwo(twice(addOne)); | |
printf("20 + 22 = %ld\n", add(20)(22)); | |
printf("41 + 1 = %ld\n", addOne(41)); | |
printf("40 + 2 = %ld\n", addTwo(40)); | |
return 0; | |
} | |