STL模板定义比较操作的方法不止一种,之前见过别人用时总是变换方式直到编译不出错为止,STL的错误提示非常长和复杂,不理解透彻将是耗时的。
实际上STL的模板提供了2种完全独立的方法,一种是使用<运算符来比较,一种是通过传入的可调用对象用,通过调用返回值来实现,本质完全不同。
前者相当于扩展对象,通过重载<,使自定义对象支持了<操作,后者通过传递比较函数,相当于回调指定“接口"。
两者情况混淆才是造成前面所提以试验为导致的解决方法混乱的原因。
以sort函数调用为例进行讲解,后文全部给出完整可运行代码以避免自行编译有错误影响分析。
第一种:不指定比较函数,默认进行<比较,重载对象的<操作,给出2种写法
#include <iostream>
#include <map>
#include <algorithm>
#include <typeinfo>
using namespace std;
class Node
{
public:
int val;
//
Node(){}
Node(int v): val(v) {}
//写法1
bool operator<(const Node& p2) const
{
return val < p2.val;
}
//end
};
//写法2
bool operator<(const Node& p1, const Node& p2) const
{
return p1.val < p2.val;
}
//end
int main()
{
Node b1, b2;
vector<Node> arr;
for(int i = 1; i < 3; i++)
{
arr.push_back(Node(i));
arr.push_back(Node(-i));
}
sort(arr.begin(), arr.end());
for(auto& item : arr)
cout << item.val << endl;
return 0;
}
第二种,传递比较“对运行对象”,也就是任何后面加上()可是合法调用的都可以。
#include <iostream>
#include <map>
#include <algorithm>
#include <typeinfo>
using namespace std;
class Node
{
public:
int val;
//
Node(){}
Node(int v): val(v) {}
};
bool my_com(const Node& p1, const Node& p2)
{
return p1.val < p2.val;
}
class MyCom
{
public:
bool operator()(const Node& p1, const Node& p2)
{
return p1.val < p2.val;
}
};
int main()
{
Node b1, b2;
vector<Node> arr;
for(int i = 1; i < 3; i++)
{
arr.push_back(Node(i));
arr.push_back(Node(-i));
}
sort(arr.begin(), arr.end(), my_com); //函数
sort(arr.begin(), arr.end(), [](const Node& p1, const Node& p2)->bool{return p1.val < p2.val;}); //lamda函数
sort(arr.begin(), arr.end(), MyCom()); //自定义可运行对象
for(auto& item : arr)
cout << item.val << endl;
return 0;
}
1、先是less<Node>指定了标准默认的less模板,()生成一个具体的可调用对象。
2、less内部执行了Node的<比较,实际又触发了Node重载的<。
#include <iostream>
#include <map>
#include <algorithm>
#include <typeinfo>
using namespace std;
class Node
{
public:
int val;
//
Node(){}
Node(int v): val(v) {}
bool operator<(const Node& p2) const
{
return val < p2.val;
}
};
int main()
{
Node b1, b2;
vector<Node> arr;
for(int i = 1; i < 3; i++)
{
arr.push_back(Node(i));
arr.push_back(Node(-i));
}
sort(arr.begin(), arr.end(), less<Node>());
for(auto& item : arr)
cout << item.val << endl;
return 0;
}
stl其他接口大体如此,函数类的多需要传递可调用对象,比如sort传递Node(),模板类的多需要传递类型,比如map的第三个参数传递Node。