前几天要用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. Ubuntu14.04LST 安装Oracle SQL Developer 4.0.2

    1:Oracle SQL Developer 4.0.2下载链接: http://www.oracle.com/technetwork/developer-tools/sql-developer/do ...

  2. C# System.Object基类

    System.Object 基类 System.Object在.Net中是所有类型的基类,任何类型都直接或间接地继承自System.Object.没有指定基类的类型都默认继承于System.Objec ...

  3. shell重定向

    输入重定向 和输出重定向一样,Unix 命令也可以从文件获取输入,语法为: command < file 这样,本来需要从键盘获取输入的命令会转移到文件读取内容. 注意:输出重定向是大于号(&g ...

  4. 转:ReportViewer控件使用方法

    a. ReportViewer关联Report1.rdlc的简单呈现b. 对带有报表参数的Report1.rdlc的呈现c. 利用程式生成的DataSet 填充报表d. 调用存储过程 生成DataSe ...

  5. Jquery时间快捷控件(Jtime)配置v1.1

    1.插件代码 /** * @title 时间工具类 * @note 本类一律违规验证返回false * @author {boonyachengdu@gmail.com} * @date 2013-0 ...

  6. 经验:Ubuntu 登陆 L2TP VPN

    Ubuntu Linux 操作系统默认支持PPTP协议的VPN登陆,但是随着网络环境的复杂化,我们需要使用L2TP协议的VPN登陆,下面,我们只需要简单的几条命令即可登陆L2TP协议的VPN.     ...

  7. Linux 多线程开发

    在任何一个时间点上,线程是可结合的(joinable)或者是分离的(detached).一个可结合的线程能够被其他线程收回其资源和杀死.在被其他线程回收之前,它的存储器资源(例如栈)是不释放的.相反, ...

  8. cmd用到的基本操作

    dir #显示当前目录中的文件和子目录 dir /a #显示当前目录中的文件和子目录,包括隐藏文件和系统文件 a = all dir c: /a:d #显示 C 盘当前目录中的目录 d = direc ...

  9. Unity 鼠标点击左右移动,人物跟随旋转

    上代码: using UnityEngine; using System.Collections; public class Test : MonoBehaviour { private Vector ...

  10. WAS下获取包路径下所有类

    最近做javaweb项目的混淆工作,用到proguard,该工具混淆.jar文件比较方便,故把所有项目代码和配置文件打成jar包, 生成的jar包经过proguard处理后,再次打包(解决progua ...