为包含指针的关联容器指定比较类型

一、等价与相等的简述

  在容器中,等价并不是相等。为什么要提等价与相等呢?因为泛型算法中的find等用于比较的是相等,即以operator==为基础,而容器成员函数的比较是以operator<为基础,所以区分二者很重要。

 1、相等

  这个很好理解,operator==返回真即代表二者相等。注:二者相等只是函数返回真,具体规则程序员可以指定的。

 2、等价

  等价关系是以“在已排序的区间中对象值的相对顺序”为基础的(Effective STL).set map排序时,就是默认的使用这种方式。即每一个都不在另一个前面。代码示意为:

  

!(w1 < w1) && ! (w2 < w1)

 3、一个忽略大小写的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 }

  显然,执行结果如下:

                            

二、为包含指针的关联容器指定比较类型。

  因为关联容器用等价进行排序,如果不指定比较类型,并且存储的是指针的话,会默认比较指针的值,而不是指针指向的对象。所以有必要对包含指针的关联容器指定比较类型。针对string*类型的如下:

  

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; // 会自动推断类型

 

posted @ 2015-06-08 22:44  TNT-boom  阅读(266)  评论(0编辑  收藏  举报