C++之Effective STL学习笔记Item21
好了,先贴一段英文,真心不想翻译过来,而且感觉也翻译不到那么到位:
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的更多相关文章
- Effective STL 学习笔记 39 ~ 41
Effective STL 学习笔记 39 ~ 41 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- 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 ...
- Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据
Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...
- Effective STL 学习笔记 32 ~ 33
Effective STL 学习笔记 32 ~ 33 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- Effective STL 学习笔记 31:排序算法
Effective STL 学习笔记 31:排序算法 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- Effective STL 学习笔记 Item 30: 保证目标区间足够大
Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...
- 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 ...
- Effective STL 学习笔记: Item 22 ~ 24
Effective STL 学习笔记: Item 22 ~ 24 */--> div.org-src-container { font-size: 85%; font-family: monos ...
- Effective STL 学习笔记 Item 21:Comparison Function 相关
Effective STL 学习笔记 Item 21:Comparison Function 相关 */--> div.org-src-container { font-size: 85%; f ...
随机推荐
- Android(java)学习笔记121:BroadcastReceiver之 自定义广播
广播使用: 电台:对外发送信号.---------电台发送广播(可以自定义) 收音机:接收电台的信号.-----广播接收者 这里,我们就说明自定 ...
- 【转】Java8学习笔记(1) -- 从函数式接口说起
http://blog.csdn.net/zxhoo/article/details/38349011 函数式接口 理解Functional Interface(函数式接口,以下简称FI)是学习Jav ...
- How to restrict root user to access or modify a file and directory in Linux
Now in this article I will show you steps to prevent or restrict access of root user to access certa ...
- spring5之SAXParseException:cvc-elt.1: 找不到元素 “beans” 的声明
之前SSM项目一直报错,就是找不到错误 气啊 后来在网上找到了答案:燕来spring5之后就不再需要写版本号了
- C11 C语言文件的读写
目录 文件的打开和关闭 字符流读写文件 文件的打开和关闭 fopen( ) fopen( ) 函数来创建一个新的文件或者打开一个已有的文件,这个调用会初始化类型 FILE 的一个对象,类型 FILE ...
- Element表单验证(2)
Element表单验证(2) 上篇讲的是async-validator的基本要素,那么,如何使用到Element中以及怎样优雅地使用,就在本篇. 上篇讲到async-validator由3大部分组成 ...
- 重装vs2008遇到的问题
由于前几天办公室电脑dhcp服务挂了,wifi网线都上不了网,很无奈只能重装了系统.于是VS2008也要重装,之前一直用的都是前一个同事留下来的软件,没自己装过,自己装的时候踩了坑,记录一下. 重装了 ...
- Spring Security 与 OAuth2(介绍)
https://www.jianshu.com/p/68f22f9a00ee Spring Security 与 OAuth2(介绍) 林塬 2018.01.23 11:14* 字数 3097 阅读 ...
- Linux-Java安装
安装 yum -y install java-1.8.0-openjdk* Tomcat安装:到官网http://tomcat.apache.org/,然后找到Tomcat9下载地址 http://m ...
- python入门:输出1-10的所有数(自写)
#!/usr/bin/env python # -*- coding:utf-8 -*- #输出1-10的所有数(自写) """ 导入time库,给kaishi赋值为数字 ...