revised
revised using std::function<>