Skip to content

Instantly share code, notes, and snippets.

@overminder
Last active August 29, 2015 14:08
Show Gist options
  • Save overminder/026659786152f8be80af to your computer and use it in GitHub Desktop.
Save overminder/026659786152f8be80af to your computer and use it in GitHub Desktop.
std::function implementation

Run

g++ -std=c++11 main.cc
./a.out

See

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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment