Use std::function for more flexibility

By using std::function, we can receive lambda, functions
and methods which gives a more flexibile interface.