#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <random>
template <typename T>
struct functor
{
T data ;
functor(const T& t) : data(t) {}
void operator()() { std::cout << data << '\n' ; }
};
struct random_functor
{
std::mt19937 engine ;
std::uniform_int_distribution<int> dist ;
random_functor(int min, int max) : engine(std::random_device()()), dist(std::min(min,max), std::max(min,max)) {}
int operator()() { return dist(engine) ; }
};
std::ostream& operator<<(std::ostream & os, random_functor& rf)
{
return os << rf() ;
}
class myclass
{
public:
myclass( std::function<void()> f = nullptr ) : _func(f) {}
void setCallback( std::function<void()> f ) { _func = f ; }
void doCallback() const { _func(); }
private:
std::function<void()> _func ;
};
int main()
{
myclass obj ;
obj.setCallback(functor<std::string>("Hello, world!")) ;
obj.doCallback() ;
obj.setCallback(functor<int>(42)) ;
obj.doCallback() ;
obj.setCallback(functor<random_functor>(random_functor(-100, 100))) ;
for ( unsigned i=0; i<10; ++i )
obj.doCallback() ;
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHJhbmRvbT4KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgZnVuY3Rvcgp7CiAgICBUIGRhdGEgOwoKICAgIGZ1bmN0b3IoY29uc3QgVCYgdCkgOiBkYXRhKHQpIHt9CgogICAgdm9pZCBvcGVyYXRvcigpKCkgeyBzdGQ6OmNvdXQgPDwgZGF0YSA8PCAnXG4nIDsgfQp9OwoKc3RydWN0IHJhbmRvbV9mdW5jdG9yCnsKICAgIHN0ZDo6bXQxOTkzNyBlbmdpbmUgOwogICAgc3RkOjp1bmlmb3JtX2ludF9kaXN0cmlidXRpb248aW50PiBkaXN0IDsKCiAgICByYW5kb21fZnVuY3RvcihpbnQgbWluLCBpbnQgbWF4KSA6IGVuZ2luZShzdGQ6OnJhbmRvbV9kZXZpY2UoKSgpKSwgZGlzdChzdGQ6Om1pbihtaW4sbWF4KSwgc3RkOjptYXgobWluLG1heCkpIHt9CgogICAgaW50IG9wZXJhdG9yKCkoKSB7IHJldHVybiBkaXN0KGVuZ2luZSkgOyB9Cn07CgpzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwoc3RkOjpvc3RyZWFtICYgb3MsIHJhbmRvbV9mdW5jdG9yJiByZikKewogICByZXR1cm4gb3MgPDwgcmYoKSAgOwp9CgpjbGFzcyBteWNsYXNzCnsKcHVibGljOgogICAgbXljbGFzcyggc3RkOjpmdW5jdGlvbjx2b2lkKCk+IGYgPSBudWxscHRyICkgOiBfZnVuYyhmKSB7fQogICAgdm9pZCBzZXRDYWxsYmFjayggc3RkOjpmdW5jdGlvbjx2b2lkKCk+IGYgKSB7IF9mdW5jID0gZiA7IH0KCiAgICB2b2lkIGRvQ2FsbGJhY2soKSBjb25zdCB7IF9mdW5jKCk7IH0KCnByaXZhdGU6CiAgICBzdGQ6OmZ1bmN0aW9uPHZvaWQoKT4gX2Z1bmMgOwp9OwoKaW50IG1haW4oKQp7CiAgICBteWNsYXNzIG9iaiA7CgogICAgb2JqLnNldENhbGxiYWNrKGZ1bmN0b3I8c3RkOjpzdHJpbmc+KCJIZWxsbywgd29ybGQhIikpIDsKICAgIG9iai5kb0NhbGxiYWNrKCkgOwoKICAgIG9iai5zZXRDYWxsYmFjayhmdW5jdG9yPGludD4oNDIpKSA7CiAgICBvYmouZG9DYWxsYmFjaygpIDsKCiAgICBvYmouc2V0Q2FsbGJhY2soZnVuY3RvcjxyYW5kb21fZnVuY3Rvcj4ocmFuZG9tX2Z1bmN0b3IoLTEwMCwgMTAwKSkpIDsKICAgIGZvciAoIHVuc2lnbmVkIGk9MDsgaTwxMDsgKytpICkKICAgICAgICBvYmouZG9DYWxsYmFjaygpIDsKfQo=