1、等價與相等的簡述ios
在容器中,等價並非相等。爲何要提等價與相等呢?由於泛型算法中的find等用於比較的是相等,即以operator==爲基礎,而容器成員函數的比較是以operator<爲基礎,因此區分兩者很重要。c++
一、相等程序員
這個很好理解,operator==返回真即表明兩者相等。注:兩者相等只是函數返回真,具體規則程序員能夠指定的。算法
二、等價函數
等價關係是以「在已排序的區間中對象值的相對順序」爲基礎的(Effective STL).set map排序時,就是默認的使用這種方式。即每個都不在另外一個前面。代碼示意爲:spa
!(w1 < w1) && ! (w2 < w1)
三、一個忽略大小寫的set程序實現:其中,忽略大小寫的set執行的比較類型。指針
1 #include <string> 2 3 struct CIStringCompare{ 4 bool operator()(const std::string& lhs, const std::string& rhs) const 5 { 6 int flag = ciStringCompare(lhs, rhs); 7 if (flag < 0) return true; 8 else return false; 9 } 10 int ciStringCompare(const std::string &lhs, const std::string &rhs) const 11 { 12 return _stricmp(lhs.c_str(), rhs.c_str()); 13 } 14 };
1 #include <set> 2 #include <iostream> 3 #include "CIStringCompare.h" 4 #include <algorithm> 5 int main() 6 { 7 // 區分大小寫 8 std::set<std::string> oriset; 9 oriset.insert("FuckC++"); 10 oriset.insert("fuckc++"); 11 12 // 不分大小寫 13 std::set<std::string, CIStringCompare> testset; 14 testset.insert("FuckC++"); 15 testset.insert("fuckc++"); 16 17 std::cout << "區分大小寫" << std::endl; 18 for_each(oriset.begin(), oriset.end(), [](const std::string& s)->void{std::cout << s << std::endl; }); 19 20 std::cout << "不區分大小寫" << std::endl; 21 for_each(testset.begin(), testset.end(), [](const std::string& s)->void{std::cout << s << std::endl; }); 22 return 0; 23 }
顯然,執行結果以下:code
2、爲包含指針的關聯容器指定比較類型。對象
由於關聯容器用等價進行排序,若是不指定比較類型,而且存儲的是指針的話,會默認比較指針的值,而不是指針指向的對象。因此有必要對包含指針的關聯容器指定比較類型。針對string*類型的以下:blog
struct StringPtrLess { bool operator()(const std::string *ps1, const std::string *ps2) const{ return *ps1 < *ps2; } };
typedef std::set<std::string*, StringPtrLess> stringPrtSet; stringPrtSet ssp; 。。。。// 操做
固然,這樣每種類型都要寫一個解引用的比較挺麻煩的,那麼咱們須要寫一個模版:
struct DereferenceLess { template<typename PtrType> bool operator()(PtrType pt1, PtrType pt2) const{ return *pt1 < *pt2; } };
typedef std::set<std::string*, DereferenceLess> stringPrtSet; stringPrtSet ssp; // 會自動推斷類型