我们可以使用自定义的cmp函数、lambda函数或者less< int >()、greater< int >()作为自定义compare对象作为参数传给sort函数,达到自定义比较顺序的结果。代码如下:
bool cmp(const int &a, const int &b){
return a
sort(vec.begin(), vec.end(), [](int a, int b){return a
sort(vec.begin(), vec.end(), less());
对于priority_queue(优先队列)可以使用仿函数(函数对象类)自定义compare顺序,代码如下:
class Cmp{
public:
bool operator()(int a, int b){
return a, Cmp> pri_que;
而自定义sort时并不能使用仿函数名Cmp,例如如下代码是错的:
// 这个代码是错的
class Cmp{
public:
bool operator()(int a, int b){
return a
这是为什么呢?
我在查资料时发现网上对仿函数的定义有冲突。
Functors are objects that can be treated as though they are a function
or function pointer.
仿函数(functor)是一个可以被视作函数或者函数指针的对象1。
这段说仿函数是一个对象,可以看做是一个函数或者函数指针。
A functor (or function object) is a C++ class that acts like a function. Functors are called using the same old function call syntax. To create a functor, we create a object that overloads the operator().
仿函数(又叫函数对象)是一个可以像函数一样运行的C++类。调用仿函数与调用函数的语法相同。为了产生一个仿函数,我们需要重载类的"()"运算法1。
这段又说仿函数是一个重载了"()"运算符的类。到底是类还是对象这里也没有说清楚。
而中文搜索的结果大多是:
仿函数又称为函数对象,是一种能够行使函数功能的类。
我个人倾向于认为仿函数是一个类,也叫函数对象类。而将仿函数实例化得到的对象(函数对象)可以看作一个函数或函数指针。下面给出代码举例:
代码举例:
// 这是一个类,仿函数(函数对象类),重载了"()"运算符
class Cmp{
public:
bool operator()(int a, int b){
return a
从sort函数的定义如下2:
template< class RandomIt, class Compare >
constexpr void sort( RandomIt first, RandomIt last, Compare comp );
可以看到sort是一个模板函数,这里需要三个输入参数(完整的sort函数并不必须要有三个输入参数,详情见2)。
第一、二个参数是需要排序的迭代器,第三个参数comp是一个Compare类的对象。
priority_queue的定义如下3:
template<
class T,
class Container = std::vector,
class Compare = std::less
> class priority_queue;
priori_queue是一个模板类,类型参数表为T、Container和Compare,这三者都是类(Class)。我们关注的Compare类默认为std::less< typename Container::value_type>。
从上面我们可以知道。对于模板函数sort,我们需要在sort的参数列表"()"中给出自定义的Compare类的对象实例,而对于模板类priority_queue,我们需要在其类型参数表 "<>"中给出自定义的Compare类。
因此使用仿函数作为cmp的合法代码如下:
class Cmp{
public:
bool operator() (int a, int b){
return a, Cmp> pri_que; //
这就是sort和priority_queue在使用仿函数做自定义比较参数时的不同。
至于为什么一个需要 使用实例化后的对象,一个需要使用类名。相信读者也可以看出,因为本质上sort是一个函数,函数参数列表中需要传入实例化后的具体对象,而priority_queue是一个模板类,模板的类型参数表中<>需要传入具体的类,而不是对象。
还有一个问题是,priority_queue的类型参数列表中需要传入类名,而lambda函数是一个匿名的类型,所以不能直接使用lambda函数声明priority_queue,需要做些改变,具体的用法可以参考这篇博客,本文中部分内容也参考了该文章。
www.geeksforgeeks.org/functors-in-cpp ↩︎ ↩︎
https://en.cppreference.com/w/cpp/algorithm/sort ↩︎ ↩︎
https://en.cppreference.com/w/cpp/container/priority_queue ↩︎