#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() ;
}
