我有一个用户定义类型(学生)的向量.我有2个函数几乎相同,除了它们内部的单个函数调用.
这是2个功能:
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();});
}
Run Code Online (Sandbox Code Playgroud)
这两个函数都可以正常使用,但似乎可以很容易地构建它.我想创建一个我可以传入min_element或max_element的函数,例如:
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();});
}
Run Code Online (Sandbox Code Playgroud)
但我无法让这个工作正常.我不知道该怎么做.
编辑 - 这是我调用调度函数+错误消息的方式:
std::cout<<"lowest: "<< dispatch(all_students, std::max_element);
Run Code Online (Sandbox Code Playgroud)
错误消息是:
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 for call to ‘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:
Run Code Online (Sandbox Code Playgroud)
您的函数可以按照您想要的方式编写,如下所示:
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();});
}
Run Code Online (Sandbox Code Playgroud)
并调用为
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&)>);
Run Code Online (Sandbox Code Playgroud)
operator<如果你实现for ,你可以大大减少冗长的内容Student。这将允许您省略比较器的模板参数。
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>);
Run Code Online (Sandbox Code Playgroud)
另一种方法是始终min_element在调度内调用,但传入具有不同行为的比较器。
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> for Student
Run Code Online (Sandbox Code Playgroud)
最后,如果您总是要获取最低和最高的成绩,标准库提供的功能std::minmax_element将在一次调用中获取这两个成绩。
auto minmax = std::minmax_element(std::begin(students), std::end(students));
Run Code Online (Sandbox Code Playgroud)
所有不同选项的现场演示。