前几天要用QSet作为储存一个自定义的结构体(就像下面这个程序一样),结果死活不成功。。。

后来还跑到论坛上问人了,丢脸丢大了。。。

事先说明:以下这个例子是错误的

  1. #include <QtCore>
  2. struct node
  3. {
  4. int cx, cy;
  5. bool operator < (const node &b) const
  6. {
  7. return cx < b.cx;
  8. }
  9. };
  10. int main(int argc, char *argv[])
  11. {
  12. QCoreApplication app(argc, argv);
  13. QSet<node> ss;
  14. QSet<node>::iterator iter;
  15. node temp;
  16. int i, j;
  17. for(i=0,j=100;i<101;i++,j--)
  18. {
  19. temp.cx = i;
  20. temp.cy = j;
  21. ss.insert(temp);
  22. }
  23. for(iter=ss.begin();iter!=ss.end();++iter)
  24. qDebug() << iter->cx << "  " << iter->cy;
  25. return 0;
  26. }

后来经过高手提醒,再经过自己看文档,才发现QSet和STL的set是有本质区别的,虽然它们的名字很像,前者是基于哈希表的,后者是红黑树的变种。。。。

QT文档中清楚地写着:In addition, the type must provide operator==(), and there must also be a global qHash() function that returns a hash value for an argument of the key's type.

简而言之,就是:
QSet是基于哈希算法的,这就要求自定义的结构体Type必须提供:
1. bool operator == (const Type &b) const
2. 一个全局的uint qHash(Type key)函数

废话说完了,上正确的代码:

  1. #include <QtCore>
  2. struct node
  3. {
  4. int cx, cy;
  5. bool operator < (const node &b) const
  6. {
  7. return cx < b.cx;
  8. }
  9. bool operator == (const node &b) const
  10. {
  11. return (cx==b.cx && cy==b.cy);
  12. }
  13. };
  14. uint qHash(const node key)
  15. {
  16. return key.cx + key.cy;
  17. }
  18. int main(int argc, char *argv[])
  19. {
  20. QCoreApplication app(argc, argv);
  21. QSet<node> ss;
  22. QSet<node>::iterator iter;
  23. node temp;
  24. int i, j;
  25. for(i=0,j=100;i<101;i++,j--)
  26. {
  27. temp.cx = i;
  28. temp.cy = j;
  29. ss.insert(temp);
  30. }
  31. for(iter=ss.begin();iter!=ss.end();++iter)
  32. qDebug() << iter->cx << "  " << iter->cy;
  33. return 0;
  34. }

以后写代码时,一定不能想当然了啊,切记!!!

http://blog.csdn.net/small_qch/article/details/7384966

QT:用QSet储存自定义结构体的问题——QSet和STL的set是有本质区别的,QSet是基于哈希算法的,要求提供自定义==和qHash函数的更多相关文章

  1. Qt--信号槽传递自定义结构体参数

    自定义结构体参数的信号槽连接 (1) 对于自定义的结构体参数,信号槽无法识别参数,导致信号槽连接不起作用.所以需要注册结构体参数.在结构体中声明结束的地方加上结构体注册. struct DealDet ...

  2. typedef和自定义结构体类型

    在自定义结构体类型时会用到typedef关键字.大家都知道typedef是取别名的意思,在C语言中跟它容易混淆的有const,#define等,其区别不在本篇文章讨论之列. /*定义单链表结点类型*/ ...

  3. qsettings 保存自定义结构体(QVariant与自定义结构体相互转化)

    参考博文:QVariant与自定义数据类型转换的方法. 这里摘取其关键内容: 1.将自定义数据类型使用Q_DECLARE_METATYPE宏进行声明,便于编译器识别. 2.在插入对象的时候,声明QVa ...

  4. iOS自定义结构体

    一.提要 通过以官方的CGSize为例,自定义Objective-C中的结构体,并使用. 二.CGSize 1.系统定义的CGSize结构体 struct CGSize { CGFloat width ...

  5. Solidity的自定义结构体深入详解

    一.结构体定义 结构体,Solidity中的自定义类型.我们可以使用Solidity的关键字struct来进行自定义.结构体内可以包含字符串,整型等基本数据类型,以及数组,映射,结构体等复杂类型.数组 ...

  6. 用set、map等存储自定义结构体时容器内部判别各元素是否相同的注意事项

    STL作为通用模板极大地方便了C++使用者的编程,因为它可以存储任意数据类型的元素 如果我们想用set与map来存储自定义结构体时,如下 struct pp { double xx; double y ...

  7. gin中绑定表单数据至自定义结构体

    package main import "github.com/gin-gonic/gin" type StructA struct { FieldA string `form:& ...

  8. Qt 信号槽传递自定义结构体

    Qt 在信号和槽中使用自己定义的结构体

  9. [UE4]自定义结构体、类、数据表

    自定义数据表: #pragma once #include "CoreMinimal.h" #include "Engine/UserDefinedStruct.h&qu ...

随机推荐

  1. mysql的client和sever之间通信password的传输方式

    本文想要说明的是,当我们用mysql -uroot -p1234567 -h127.0.0.1 -P3306 去连接mysql server时密码是通过什么样的形式传过去的呢? 首先密码这种东西明文传 ...

  2. EF调用存储过程实例

    创建实体: public class User { public string UserID { get; set; } public string UserName { get; set; } pu ...

  3. FAT16文件系统简介

    有必要说明一下,以下对FAT16系统的介绍,很多都是参考文献.由于FAT16系统一般在U盘.MMC卡.SD卡以及一些小型存储设备上使用比较多,以后把这些小型存储设备统称为存储卡,这里仅局限于对存储卡的 ...

  4. C# 调用 Web Service

    Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术.是:通过SOAP ...

  5. SQL Serverf 索引 - 索引压缩 、附加特性 <第十篇>

    一.索引压缩 数据和索引压缩在SQL Server2008被引入.压缩一个索引意味着将在一个页面中获得更多的关键字信息.这可以造成重大的性能改进,因为存储索引需要的页面和索引级别更少.因为索引中的键值 ...

  6. Android中退出多个Activity的两个经典方法

    这里介绍两种方法:一种把每个activity记住,然后逐一干掉:另一种思路是使用广播. 方法一.用list保存activity实例,然后逐一干掉 上代码: import java.util.Linke ...

  7. UESTC_温泉旅店 CDOJ 878

    天空飘下一朵一朵的雪花,这是一片纯白的世界. 在天空之下的温泉旅店里,雪菜已醉倒在一旁,冬马与春希看了看说着梦话的雪菜,决定找一点玩的来度过这愉快的晚上. 这家旅店提供一种特色游戏,游戏有n张牌,各写 ...

  8. 什么是优先级队列(priority queue)?

    有时候我们需要在某个元素集合中找到最小值和最大值 .优先级队列抽象数据(Priority Queue ADT)模型是我们能够使用的方法之一,这是一种支持插入和删除最小值(DeleteMin)或者最大值 ...

  9. Eight(South Central USA 1998)(八数码) 分类: bfs 2015-07-05 22:34 1人阅读 评论(0) 收藏

    The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...

  10. PHP代码,拒绝频繁访问

    一个网站性能有限,如果有人恶意去频繁对页面进行刷新,其实对服务器影响是很大的,导致资源使用非常高,直接影响到其他用户的体验. 那么对于这样的一些频繁访问,我们该如何去拒绝它呢? 我总结了两种方法:第一 ...