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。