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


    一、等价与相等的简述

      在容器中,等价并不是相等。为什么要提等价与相等呢?因为泛型算法中的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; // 会自动推断类型
  • 相关阅读:
    spring读书笔记----Quartz Trigger JobStore出错解决
    Linux:Ubuntu16.04下创建Wifi热点
    Java:IDEA下使用JUNIT
    MYSQL:基础—存储过程
    StackExchange.Redis加载Lua脚本进行模糊查询的批量删除和修改
    EFCore执行Sql语句的方法:FromSql与ExecuteSqlCommand
    .NET Core配置文件加载与DI注入配置数据
    ASP.NET Core实现OAuth2.0的AuthorizationCode模式
    CSS实现的几款不错的菜单栏
    开发VS2008 AddIn 入门Sample
  • 原文地址:https://www.cnblogs.com/tntboom/p/4562175.html
Copyright © 2020-2023  润新知