将STL算法传递给另一个函数

r-s*_*r-s 7 c++ stl c++11

我有一个用户定义类型(学生)的向量.我有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)

Pra*_*ian 1

您的函数可以按照您想要的方式编写,如下所示:

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)

所有不同选项的现场演示。