【问题标题】:Why do Qt containers like QList and QVector not have iterator range constructors?为什么像 QList 和 QVector 这样的 Qt 容器没有迭代器范围构造函数?
【发布时间】:2016-11-10 18:00:17
【问题描述】:

C++ 中的标准库容器具有采用迭代器范围的构造函数。当输入容器的内容可转换为但与结果容器中的内容不同时,这很方便,或者即使容器只是不同。构造函数重载允许这种类型的转换发生在周围类的构造函数中,从而减少代码中的混乱。

那么问题来了,为什么 Qt 容器没有这种过载?是疏忽还是这种笨拙的设计选择背后有什么原因?

【问题讨论】:

    标签: qt iterator-range


    【解决方案1】:

    除了“到目前为止没有人实现它们”之外没有其他原因,因为 Qt 项目没有无限的开发带宽。

    说到这些缺失的功能,你可以这样说:

    • 由于隐式共享,您无法在 Qt 容器中存储仅移动类型;
    • 缺少定位功能(以及它们即将推出的关联容器试用版本);
    • 缺少右值重载函数(没有QList::push_back(T &&));
    • QList 在 STL 中没有等效项,并且是一个非常奇怪的怪物,具有严重的性能问题。现在承认它不应该成为 Qt 中随处使用的“良好的通用容器”;
    • 没有任何异常安全保证;

    等等。

    最近有很多关于 Qt 容器与 STL 容器相比状态不佳的讨论(参见 this thread),以至于我们开始在 Qt 自己的实现中使用 STL 容器。

    除非您有使用 Qt 的特定原因(例如,您需要将它们传递给 Qt-ish API,或者您喜欢/需要隐式共享等),现在 STL 容器比 Qt 容器要好得多。


    更新:Qt 6 中的 QList 将是一个适当的向量,而 QVector(在 Qt 6 中)将是 QList 的别名。上面的一些评论将不再适用。我不会修改答案的其余部分,因为它仍然适用于 Qt 5.15。

    【讨论】:

    • 前三个可以归咎于 C++11 尚未集成(这实际上只是在 Qt 5.7 中才开始发生。异常安全,嗯,是的,我猜他们走的是容易的路他们自己“没有例外”。STL 迭代器范围构造函数一直存在。
    • 这还不是全部。在 5.7 中强制使用 C++11 编译器,但 Qt 从 5.0 开始(有条件地)支持 C++11 构造。他们只是#ifdef'd 在代码中。对只移动类型的支持在设计上是拙劣的:任何容器的operator[] 都需要发出在引用计数大于一时分离的代码,并且分离需要可用的复制构造函数。顺便说一句,您可以对异常支持说同样的“永远”,不需要强制公共默认构造函数等等。
    • 啊,好的。嗯,太糟糕了。因为 Qt 确实有很多有用的特性,我认为没有一个框架具有相同的规模和(除了这些问题)实现质量......
    • 实际上是雪上加霜:为什么有人想添加QList<T> QVector<T>::toList(),而不是远程构造函数?
    • "由于隐式共享,您不能在 Qt 容器中存储仅移动类型;"为什么隐式共享会阻止仅移动类型?在我看来,这样的容器永远不会被隐式共享,所以我们永远不需要“复制”/分离容器。能详细点吗?
    【解决方案2】:

    Qt 容器中缺少 STL 容器的几个特性。您可以在 Marc Mutz here 的博客中找到对它们的精彩评论。

    在我看来,计划是用qCopyhttp://doc.qt.io/qt-4.8/qtalgorithms.html 替换构造中的迭代器范围的特性。在 Qt 5 中,许多用于容器的 iteratorconst_iterator 特性出现在 Qt 中,并且可能适合 QList 和 QVector 的构造函数也可能出现在以后的版本中(未公布,只是一个想法)。

    【讨论】:

      猜你喜欢
      • 2014-09-18
      • 2023-04-01
      • 1970-01-01
      • 2011-08-13
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      • 2016-03-22
      • 2016-11-28
      相关资源
      最近更新 更多