前几天要用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. java中Timer计时器使用

    1.新建计时器Timer对象 2.给计时器安排任务,schedule方法 3.取消计时器中分配的任务,purge方法 4.终止计时器,cancel方法 注意:如果计时器已经终止,还要给计时器安排任务, ...

  2. Mysql.Data的连接驱动 .net 的源码竟然在git了

    如标题 上链接:https://github.com/mysql/mysql-connector-net

  3. maven添加oracle jdbc依赖

    maven添加oracle jdbc依赖 由于Oracle授权问题,Maven不提供Oracle JDBC driver,为了在Maven项目中应用Oracle JDBC driver,必须手动添加到 ...

  4. 关于找不到stdafx.h头文件问题

    代码: #include "stdafx.h" #include "stdlib.h" char* getcharBuffer() { return " ...

  5. zb的生日(暴搜dfs)

    zb的生日 时间限制:3000 ms  |  内存限制:65535 KB 难度:2   描述 今天是阴历七月初五,acm队员zb的生日.zb正在和C小加.never在武汉集训.他想给这两位兄弟买点什么 ...

  6. ubuntu 14.04 chromium 设备adobe flash player(亲测可行)

    首先,根据浏览器提示下载Adobe Flash Player 插入 install_flash_player_11_linux.x86_64.tar.gz;然后使用sudo tar -xzvf ins ...

  7. &lt;源代码&gt;FTPclient追加方式上传自己定义信息

    实现功能:向FTPserver以追加方式上传自己定义信息(例程中为:2014-10-08 13:47:15 test.) 源代码下载(免积分):http://download.csdn.net/det ...

  8. angular在ie8下的一个bug

    昨天拿项目在ie8下测试,发现不少bug,其中有一个bug让我很不解,报了一个thead开头的bug,因为已经切回到linux下了,我就不报具体是什么bug了,鼓捣了半天,发现引用angular的应用 ...

  9. jQuery UI的基本使用方法与技巧

    一.概述 jQuery UI is a widget and interaction library built on top of the jQuery JavaScript Library, th ...

  10. android实现透明和半透明效果

    从透明到半透明时一个值的变化过程. #00000000(全透明)——#e0000000(半透明) 如果觉得半透明的效果太暗淡.可以设置成#60000000,#80000000,#a0000000等等