这两天忙着在准备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解析的更多相关文章

  1. python_paramiko_SSHException Invalid requirement, parse error at

    不加sleep(0.5)会出现SSHException: Invalid requirement, parse error at " '' "问题,原因暂时未知. 结论如下 如果不 ...

  2. STL sort “invalid operator <”

    跟踪了下,是比较函数(下面的_Pred)的问题: template<class _Pr, class _Ty1, class _Ty2> inline bool _Debug_lt_pre ...

  3. c++中sort函数调用报错Expression : invalid operator <的内部原理 及解决办法

    转自:https://www.cnblogs.com/huoyao/p/4248925.html 当我们调用sort函数进行排序时,中的比较函数如果写成如下 bool cmp(const int &a ...

  4. c++中sort函数调用报错Expression : invalid operator <的内部原理

    当我们调用sort函数进行排序时,中的比较函数如果写成如下 bool cmp(const int &a, const int &b) { if(a!=b) return a<b; ...

  5. Spark in action on Kubernetes - Spark Operator的原理解析

    前言 在上篇文章中,向大家介绍了如何使用Spark Operator在kubernetes集群上面提交一个计算作业.今天我们会继续使用上篇文章中搭建的Playground进行调试与解析,帮助大家更深入 ...

  6. 解决Linux下编译.sh文件报错 unexpected operator Syntax error: word unexpected

    执行一个脚本  发现报语法错误,但是在其他机器上运行都没有问题 唯一的区别就是 一个是centos机器  报错的是ubuntu 网上搜索了一下 因为Ubuntu默认的sh是连接到dash的,又因为da ...

  7. 问题:编译eshoponcontainers失败,提示error:invalid reference format

    环境: visual studio 2017 v15.4.2,docker ce Version 17.06.0-ce-win19 (12801) 参考问题页: https://github.com/ ...

  8. “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 ...

  9. System Error Codes

    很明显,以下的文字来自微软MSDN 链接http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx M ...

随机推荐

  1. SpringCloud 教程 (三)高可用的服务注册中心

    一.准备工作 Eureka can be made even more resilient and available by running multiple instances and asking ...

  2. 170817关于Listener的知识点

    1.  Listener   监听器简介                    Listener是JavaWeb中三大组件之一.Servlet.Filter.Listener              ...

  3. 为什么Redis可以方便地实现分布式锁

    1.Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系. 2.Redis的SETNX命令可以方便的实现分布式锁. setNX(SET if  ...

  4. HDU6599 (字符串哈希+回文自动机)

    题意: 求有多少个回文串的前⌈len/2⌉个字符也是回文串.(两组解可重复)将这些回文串按长度分类,分别输出长度为1,2,...,n的合法串的数量. 题解:https://www.cnblogs.co ...

  5. ORA-00972

    SQL> select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') as 日期时间 from dual;select to_char(sysdate,'YY ...

  6. 用Vue来实现音乐播放器(五):路由配置+顶部导航栏组件开发

    路由配置 在router文件夹下的index.js中配置路由 import Vue from 'vue' import Router from 'vue-router'//配置路由前先引入组件impo ...

  7. Delphi XE2 之 FireMonkey 入门(5) - TAlphaColor

    不是 TColor, 是 TAlphaColor 了. TAlphaColor = type Cardinal; 还是一个整数. 四个字节分别是: AA RR GG BB(透明度.红.绿.蓝); 这和 ...

  8. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_1_IO概述(概念&分类)

  9. Oracle数据库文件导出为CSV格式的方法

    1 安装PLSQL Developer,并连接Oracle数据库. 2 执行sql语句,将要导出的表格显示出来. select * from table名; 3 如下点击导出查询结果,选择数据格式,即 ...

  10. ODBC Driver Development

    ODBC Driver Development By Vikash Agarwal, May 01, 2002 Open your database system to the world. Vika ...