【问题标题】:QMap and QPair, C++, QtQMap 和 QPair、C++、Qt
【发布时间】:2011-10-04 09:38:49
【问题描述】:

我想通过两种方式制作一个用于访问字符串的数据结构:

  1. 通过 ID 访问
  2. 按名称访问

我的第一个想法是为每种方法使用两个映射,但这会导致数据重复:

QMap<int, QString> accessById;
QMap<QString, QString> accessByName;

我正在寻找更好的方法,如下所示:

QMap<QPair<int, QString>, QString> multiAccess;

但它不能帮助我(至少我不知道该怎么做),因为在地图中搜索需要同时知道 ID 和名称。如何定义 Qt 类的良好结构以实现我的目标?

没有外部库,但是 Qt

【问题讨论】:

标签: c++ qt data-structures


【解决方案1】:

怎么样:

QMap<QString, int> nameIdMap;
QMap<int, QString> accessById;

您通过 id 访问并为名称和 id 创建一个映射。然后你可以通过名称访问

QString data = accessById[nameIdMap[the_name]];

【讨论】:

  • +1 用于稍微降低内存要求,但请注意 QString 在后台隐式共享,因此双重查找与内存的对比可能不像它可能那样明显获胜与其他字符串实现一起使用:doc.qt.nokia.com/latest/implicit-sharing.html
  • @MasoudM。 QPair 仅适用于您希望将 (1, "Foo")(2, "Foo")(1, "Bar") 等映射到不同值的键。如果您对基于通配符键的有效模式匹配的语言感兴趣,例如(1, *)(*, "Foo"),它们就在那里......但是C++ 中QMap 中的QPair 不能那样工作.
【解决方案2】:

由于“隐式共享”,Qt 不像许多其他类库那样担心数据重复:

http://doc.qt.nokia.com/latest/implicit-sharing.html

具有此属性的类列表(包括QString)包含在该链接中。有一些助手可以创建您自己的类,它们也使用 Copy-On-Write 策略:

http://en.wikipedia.org/wiki/Copy-on-write

http://doc.qt.nokia.com/latest/qshareddatapointer.html#details

总结一下:如果您有一个 10,000 个字符的 QString 并将其分配给另一个 QString 变量,您将不会再支付 10,000 个字符的存储空间(除非您修改两个实例之一的字符串数据)。尽管如此,即使是只读的 QString 句柄也比 int 大一点。这取决于您的情况,这种大小差异是否显着与多次查找的速度折衷相比,就像@Juho 提供的策略一样。

【讨论】:

  • +1:对我来说很好。好的,我如何将 QStrings 放到 implicit sharing 适用于它们的两个映射中?
  • 正如“隐式”一词所表明的那样,它无需您做任何特别的事情就可以工作。每次执行 QString 赋值(包括作为映射中的键或值)时,该赋值不会复制底层字符串数据。每个新的值复制 QString 将只是一个指向共享数据的指针......直到有人在某处写入他们的实例。在撰写本文时,数据是重复的。所有这些都在幕后以线程安全的方式发生。
  • 所以如果我写QString a="Hello";QString b="Hello"; 那么ab 指的是共享数据块?
  • 嗯,它可能......但如果确实如此,那将与 Qt 没有任何关系,而是称为“常量池”或“字符串实习”的编译器功能,您可以调查是否你希望。该案例更多的是关于QString a="Hello";QString b=a;,它们不需要运行时字符串比较来做出内存管理决策...
  • 注意:查看 Qt 源代码,没有检查传入的 char* 指针在多个调用中是否相同,因此您的 a/b 示例版本肯定会分配单独的数据...即使编译器合并常量并两次传递相同的地址。
【解决方案3】:

您可以使用Boost Bimap,它将在 id 和 Name 之间创建一个双向映射。

boost::bimap<int, QString> idNameBimap;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 2019-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多