好了,先贴一段英文,真心不想翻译过来,而且感觉也翻译不到那么到位:

The STL is awash in comparisons of objects to see if they have the same value. For example, when you ask find to locate the first object in a range with a particular value, find has to be able to compare two objects to see if the value of one is the same as the value of the other. Similarly, when you attempt to insert a new element into a set, set::insert has to be able to determine whether that element’s value is already in the set.

The find algorithm and set’s insert member function are representative of many functions that must determine whether two values are the same. Yet they do it in different ways. find’s definition of “the same” is equality, which is based on operator==. set::insert’s definition of “the same” is equivalence, which is usually based on operator<.

Operationally, the notion of equality is based on operator==. If the expression “x == y” returns true, x and y have equal values, otherwise they don’t.

x and y have equivalent values with respect to operator< if the following expression is true:

!(x < y) && !(y < x)

好了,关于等价和等值的讨论,我们先到此为止。我们引入下一话题,假设我们现在创建如下一个set:

set<int, less_equal<int> > s; // s is sorted by “<=”

向其中插入10:

s.insert();

然后再向其插入10,我们知道,set中的元素是没有重复的,所以程序会判断10是否已经在当前set中,为了方便说明,我们把第一个插入的10称为10A,第二个称为10B。set的判断过程会是10A和10B是否是一样的,set所定义的一样就是我们之前提到的equivalence

那么程序中的less_equal是怎么来判断的呢?我们根据上面的推导,一个合理的推导,set可能是这样来判断的:

!(10A <= 10B) && !(10B <= 10A)      // test 10A and 10B for equivalence

当然上头的判定的结果为:!(true) && !(true) ,等价于 false && false,所以最终的结果会是false,也就是说,判定结果告诉我们,10A和10B is not equivalent!然后10B,也就是10会被再一次插入到set中,oh, no!

好了,这只是个玩笑,set可不会弱到如此地步,set中是不会存在重复元素的。小伙伴们肯定觉得疑惑了,这说了半天有毛用啊,set又不会使用less_equal这样的顺序,因为压根就不允许equal的情况发生,你这不是找别扭呢嘛!

别急,set有不重复这个特性,那么要是是个multiset呢,按照这个思路,这样的操作一定会成功,会认为是两个不同的元素插入到multiset内部,假设我们在后面需要做equal_range的相关操作(it identifies a range of equivalent values),问题就大了!

哈哈,和大家开了个很大的玩笑,STL是经过千锤百炼的,怎么可能存在这样傻的问题!关于这个问题SGI是最权威的了,我们可以去SGI查查,看到底是怎么回事!还真有,关键字:Strict Weak Ordering,好了让我们看看是怎么解决这个问题的:

明白了吧,人家是避免<=这样的比较出现,怎样避免?我目前认为避免的意思就是不能这样,这样就不行,看代码吧:

multiset<int, less_equal<int> > s;
s.insert();
s.insert();

这段代码编译通过,但是执行时会报assert错误!我没有搞清楚其中的原理,继续研究吧!

好了,绕了这么一大圈,其实就是想告诉你,在实现自己的类似less_equal仿函数的时候,一定要留神了,千万不要存在这样的bug!

感谢大家的阅读,希望能帮到大家!

Published by Windows Live Writer.

C++之Effective STL学习笔记Item21的更多相关文章

  1. Effective STL 学习笔记 39 ~ 41

    Effective STL 学习笔记 39 ~ 41 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  2. Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value

    Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value */--> div.org-src-container ...

  3. Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据

    Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...

  4. Effective STL 学习笔记 32 ~ 33

    Effective STL 学习笔记 32 ~ 33 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  5. Effective STL 学习笔记 31:排序算法

    Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

  6. Effective STL 学习笔记 Item 30: 保证目标区间足够大

    Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...

  7. Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor

    Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor */--> div ...

  8. Effective STL 学习笔记: Item 22 ~ 24

    Effective STL 学习笔记: Item 22 ~ 24 */--> div.org-src-container { font-size: 85%; font-family: monos ...

  9. Effective STL 学习笔记 Item 21:Comparison Function 相关

    Effective STL 学习笔记 Item 21:Comparison Function 相关 */--> div.org-src-container { font-size: 85%; f ...

随机推荐

  1. 2017.10.6 QBXT 模拟赛

    题目链接 T1 Sort 一下与原数组比较 ,若有两个数或者没有数发生位置交换 ,则输出YES ,否则输出NO #include <algorithm> #include <ccty ...

  2. 给VS2008 打补丁

    vs2003到2008各版本如下: vs.net2003 Visual Studio .NET 2003 Enterprise Architect Visual Studio .NET 2003 En ...

  3. xcode技巧

    1.统计ios开发代码,包括头文件的,终端命令进入项目目录下,命令如下 find . -name "*.m" -or -name "*.h" -or -name ...

  4. 使用Timer组件实现人物动画效果

    实现效果: 知识运用: Graphics类的DrawImage方法 //在指定位置 按原始大小绘制指定的Image对象 public void DrawImage(Image image,Point ...

  5. deque 用法

    引用博客:https://blog.csdn.net/zyq522376829/article/details/46801973 下面是那位大佬写的的笔记整理~~~~ deque - 双向队列 1.构 ...

  6. Java中将字符串与unicode的相互转换工具类

    unicode编码规则 unicode码对每一个字符用4位16进制数表示.具体规则是:将一个字符(char)的高8位与低8位分别取出,转化为16进制数,如果转化的16进制数的长度不足2位,则在其后补0 ...

  7. Python正则表达式详解——re库

    一.简介 1.1.相关链接 官方文档: Python2:https://docs.python.org/2/library/re.html Python3:https://docs.python.or ...

  8. java中常用的集合的一些区别 (2013-10-07-163写的日志迁移

    java中的以下几大集合: List结构的集合类: ArrayListl类,LinkedList类,Vector类,stack类 Map结构的集合类: HashMap类,Hashtable类(此是以k ...

  9. Kafka 基础实战 :消费者和生产者实例

    学习地址: http://www.jikexueyuan.com/course/2036.html

  10. python可视化动态图表: 关于pyecharts的sankey桑基图绘制

    最近因工作原因,需要处理一些数据,顺便学习一下动态图表的绘制.本质是使具有源头的流动信息能够准确找到其上下级关系和流向. 数据来源是csv文件 导入成为dataframe之后,列为其车辆的各部件供应商 ...