c++ - Passing STL algorithm to another function -
i have vector of user defined type (student). have 2 functions identical except single function call inside them.
here 2 functions:
student lowest_grade(const std::vector<student> &all_students){ return *std::min_element(std::begin(all_students), std::end(all_students), [](const student &a, const student &b){ return a.get_average() < b.get_average();}); } student highest_grade(const std::vector<student> &all_students){ return *std::max_element(std::begin(all_students), std::end(all_students), [](const student &a, const student &b){ return a.get_average() < b.get_average();}); }
both of these functions working correctly use seems constructed better. want create function pass in either min_element or max_element, like:
template <typename func> student dispatch(const std::vector<student> &all_students, func){ return *func(std::begin(all_students), std::end(all_students), [](const student &a, const student &b){ return a.get_average() < b.get_average();}); }
but can't manage work properly. not sure how go doing this.
edit - how calling dispatch function + error message:
std::cout<<"lowest: "<< dispatch(all_students, std::max_element);
the error message is:
g++ m.cpp -std=c++11 -wall -o main m.cpp: in function ‘int main()’: m.cpp:86:63: error: missing template arguments before ‘(’ token std::cout<<"lowest: "<< dispatch(all_students, std::function(std::max_element)); ^ ryan@ryan-virtualbox:~/desktop/prog/daily/167m$ make g++ m.cpp -std=c++11 -wall -o main m.cpp: in function ‘int main()’: m.cpp:86:81: error: no matching function call ‘dispatch(std::vector<student>&, <unresolved overloaded function type>)’ std::cout<<"lowest: "<< dispatch<std::function>(all_students, std::max_element); ^ m.cpp:86:81: note: candidate is: m.cpp:71:9: note: template<class func> student dispatch(const std::vector<student>&, func) student dispatch(const std::vector<student> &all_students, func){ ^ m.cpp:71:9: note: template argument deduction/substitution failed:
your function can written way want follows:
template<typename func> student dispatch(const std::vector<student> &all_students, func func) { assert(!all_students.empty()); return *func(std::begin(all_students), std::end(all_students), [](const student &a, const student &b){ return a.get_average() < b.get_average();}); }
and invoked as
dispatch(students, std::min_element<decltype(students)::const_iterator, bool(*)(const student&, const student&)>); dispatch(students, std::max_element<decltype(students)::const_iterator, bool(*)(const student&, const student&)>);
you can cut down on verbosity quite bit if implement operator<
student
. allow omit template argument comparator.
template<typename func> student dispatch(const std::vector<student> &all_students, func func) { assert(!all_students.empty()); return *func(std::begin(all_students), std::end(all_students)); } dispatch(students, std::min_element<decltype(students)::const_iterator>); dispatch(students, std::max_element<decltype(students)::const_iterator>);
yet way this, call min_element
within dispatch, pass in comparators different behaviors.
template<typename comparator> student dispatch(const std::vector<student> &all_students, comparator comp) { assert(!all_students.empty()); return *std::min_element(std::begin(all_students), std::end(all_students), comp); } dispatch(students, std::less<student>()); dispatch(students, std::greater<student>()); // requires operator> student
finally, if you're going fetch both lowest , highest grades, standard library offers std::minmax_element
fetch both in single call.
auto minmax = std::minmax_element(std::begin(students), std::end(students));
live demo of different options.
Comments
Post a Comment