Invalid operator< assertion error解析
这两天忙着在准备3月份打PAT考试,许久没有接触刷题了,各种生疏各种忘记,刷题速度那是一个慢,真是为自己智商着急。今天刷题碰到了一个有意思的编程习惯性错误,好几道题都涉及到自定义排序,需要自己重写<操作符号,我在调试的时候,程序提示assertion error: Invalid operator<,思考了很久也没有发现问题,在网上搜寻了这个问题,大概是理解了,将我对这个问题的理解总结一下。
案例:如自定义结构体Cmp
struct Cmp
{
int field1,field2;
bool operator<(const Cmp& cmp)
{
if(this->field1 < cmp.field1) return true;
else if(this->field2 < cmp.field2) return true;
return false;
}
};
此结构体的大小主要是按照field1进行排列,如果field1排不出来,就按照field2进行排列。这段代码看上去没有什么问题,但是如果使用algorithm stl中的sort函数对含有此类型的数组进行排序,在debug模式下会出现断言失败的提示,即invalid operator<,表示这个自定义的比较函数不严格,可能会有问题。
仔细分析,也很容易看出来这段代码错在什么地方,在第二个if判断中,我们仅仅是判断了第二个field大小,忘记加上对第一个field的限制了,把该if判断改成
else if(this->field2 < cmp.field2 && this->field1 == cmp.field1)
发现警告消失了,为什么会这样呢?标准库中的sort函数为什么要我们这么写?
sort函数要求比较函数是strict weak ordering的,而strict weak ordering必须满足三个条件:
1) Strict: pred (X, X) is always false. X跟X自己比为false
2) Weak: If ! pred (X, Y) && !pred (Y, X), X==Y. 当X<Y和Y<X都不成立时,X等于Y
3)Ordering: If pred (X, Y) && pred (Y, Z), then pred (X, Z). 当X<Y,Y<Z时,X<Z成立,即排序的一个传递性。
用一个实例来说明问题。假设有三个变量,m1(1,2),m2(2,1),m3(1,2)。(括号内的两个数分别表示field1和field2的值。在前面有问题的代码下,我们可以判断:
1)m1<m2,并且m2<m3,根据条件3,m1<m3,但是很明显m1跟m3是一样的,应该是相等的!
2)也可以发现在该规则下,m2<m1也成立!根据条件1,推导出m1竟然与m2相等,m1==m2!
这两个情况明显不符合常理,如果允许程序这样运行,最后的结果谁也想不到会排成什么样子。
综上所述,在写比较函数的时候一定要小心,不要粗心大意漏掉了条件。这也告诫了我们编译器给出的各种提示警告,还是老老实实地去遵守比较好,不然到后来吃了哑巴亏也不知道是什么地方出了问题。
Invalid operator< assertion error解析的更多相关文章
- python_paramiko_SSHException Invalid requirement, parse error at
不加sleep(0.5)会出现SSHException: Invalid requirement, parse error at " '' "问题,原因暂时未知. 结论如下 如果不 ...
- STL sort “invalid operator <”
跟踪了下,是比较函数(下面的_Pred)的问题: template<class _Pr, class _Ty1, class _Ty2> inline bool _Debug_lt_pre ...
- c++中sort函数调用报错Expression : invalid operator <的内部原理 及解决办法
转自:https://www.cnblogs.com/huoyao/p/4248925.html 当我们调用sort函数进行排序时,中的比较函数如果写成如下 bool cmp(const int &a ...
- c++中sort函数调用报错Expression : invalid operator <的内部原理
当我们调用sort函数进行排序时,中的比较函数如果写成如下 bool cmp(const int &a, const int &b) { if(a!=b) return a<b; ...
- Spark in action on Kubernetes - Spark Operator的原理解析
前言 在上篇文章中,向大家介绍了如何使用Spark Operator在kubernetes集群上面提交一个计算作业.今天我们会继续使用上篇文章中搭建的Playground进行调试与解析,帮助大家更深入 ...
- 解决Linux下编译.sh文件报错 unexpected operator Syntax error: word unexpected
执行一个脚本 发现报语法错误,但是在其他机器上运行都没有问题 唯一的区别就是 一个是centos机器 报错的是ubuntu 网上搜索了一下 因为Ubuntu默认的sh是连接到dash的,又因为da ...
- 问题:编译eshoponcontainers失败,提示error:invalid reference format
环境: visual studio 2017 v15.4.2,docker ce Version 17.06.0-ce-win19 (12801) 参考问题页: https://github.com/ ...
- “Debug Assertion” Runtime Error on VS2008 VS2010 winhand.cpp
I'm writing a C++ MFC program on VS2008 and I'm getting this "Debug Assertion Error" when ...
- System Error Codes
很明显,以下的文字来自微软MSDN 链接http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx M ...
随机推荐
- 3D Computer Grapihcs Using OpenGL - 11 Model View Projection Matrices
本节我们将绘制一个3维物体,立方体. 如果要渲染3D物体,我们需要了解MVP(Model View Projection),它表示三个转换矩阵.实际上这个名字不够明确,更加确切的释义如下: Model ...
- es之关于consistency(数据一致性问题)
Es集群内部是有一个约定是用来约束我们的写操作的,就是“一致性”: 也就是说:新建.索引.删除这些操作都是写操作,他们都有一个大前提: 当前的分片副本处于活跃状态的数量 >= int( (pri ...
- 笨办法学Python(learn python the hard way)--练习程序41
下面是练习41,基于python3 #ex41.py 1 #打印文档字符串 print(函数名.__doc__) 2 from sys import exit 3 from random import ...
- CSS中clip-path属性的使用
clip-path的使用 polygon 值为多个坐标点组成,坐标第一个值是x方向,第二个值是y方向. 左上角为原点,右下角是(100%,100%)的点.</p> body { backg ...
- 状压dp(8.8上午)
神马是状态压缩? 就是当普通dp的每一维表示的状态非常少的时候,可以压缩成一维来表示 如果m==8 dp[i][0/1][0/1]......[0/1] 压缩一下 dp[i][s]表示到了第i行,状态 ...
- ios 无法安装xxx,请稍后再试
通过xcode可以用模拟机器运行工程,但是 打出包后: 真机安装提示 无法安装xxx,请稍后再试 已经信任了证书 问题原因:xcode配置的 运行手机上的操作系统太高了是 解决办法:deploymen ...
- python实现格式化输出9*9乘法表
# python 9*9 乘法表 for i in range(1,10): for j in range(1,i+1): print("%s*%s=%s"%(i,j,i*j),e ...
- 阶段1 语言基础+高级_1-3-Java语言高级_03-常用API第二部分_第6节 基本类型包装类_1_包装类的概念
只有这两个比较特殊
- Android安全测试(三)应用完整性检验检测
二.app应用完整性1.测试环境 SDK: Java JDK, Android SDK. 工具: 7zip,apktool.jar,signapk.jar 2.操作步骤 第一步:把需要检测的apk放置 ...
- python自动化测试接口测试http请求报404的其中一个坑
在敲代码的路上 ,总是会遇到报错找半天原因,最后发现是个低级错误的时候! 这不今天为了这个错误找了半天原因.......... http请求接口测试中报404我遇到的大部分都是url的问题: 但是今天 ...