using std::function instead of templates