为什么Qt的容器,例如QList和QVector没有迭代器范围构造函数?

3

C++的标准库容器有可以使用迭代器范围作为参数的构造函数。当输入容器的内容可转换为结果容器的内容,但不相同甚至容器不同的情况下,这会非常方便。构造函数重载允许在包含类的构造函数中进行此类型的转换,从而减少代码混乱。

因此,问题出现了:为什么Qt容器没有这种重载?这是一个疏忽还是设计选择背后有原因呢?

2个回答

7
除了"之前没有人实现它们"这个原因外,没有其他原因,因为Qt项目没有无限的开发带宽。
谈到这些缺失的功能,你也可以说同样适用于:
- 由于隐式共享,您无法在Qt容器中存储仅移动类型; - 缺少插入函数(及其即将推出的关联容器的try版本); - 缺少rvalue-overloaded函数(没有); - QList在STL中没有相应物,并且是一个非常奇怪的怪物,存在严重的性能问题。现在已经承认,它本不应该成为Qt中到处使用的“好通用容器”; - 没有任何异常安全性保证;
等等。
最近有很多讨论(例如请参见此线程),比较Qt容器与STL容器时的贫瘠状态,甚至我们开始在自己的实现中使用STL容器。
除非您有使用Qt容器的特定原因(例如,需要将它们传递给Qt-ish API,或者您喜欢/需要隐式共享等),否则这些日子里STL容器比Qt容器更好。

1
前三个问题可以归咎于C++11尚未集成(这实际上只在Qt 5.7开始发生)。异常安全性,嗯,我想他们选择了告诉自己“没有异常”的简单路线。STL迭代器范围构造函数一直存在,呃,永远存在。 - rubenvb
1
这并不是全部的故事。在5.7中,C++11编译器成为了必须的,但Qt自5.0以来就有(有条件的)支持C++11构造。它们只是在代码中被#ifdef掉了。然而,对于仅移动类型的支持设计存在缺陷:任何容器的operator[]都需要发出代码以进行分离,如果引用计数大于1,则需要可用的复制构造函数进行分离。顺便说一句,关于异常支持,你可以永远这样说,不需要强制公开默认构造函数等等。 - peppe
啊,好的。那太遗憾了。因为Qt确实拥有许多有用的功能,我认为除了这些问题之外,没有一个框架具有相同的规模和质量实现... - rubenvb
“无法在Qt容器中存储移动类型是由于隐式共享的原因。”为什么隐式共享会阻止移动类型?在我看来,这样的容器永远不会被隐式共享,因此我们永远不需要“复制/分离”容器。您能否详细说明一下? - Johannes Schaub - litb
@JohannesSchaub-litb:实际上我需要修改之前的评论,但显然我不能...你是对的,它并没有阻止它,它只是使代码比应该的复杂得多。容器只需要在周围添加一些enable_if来禁用复制操作,并可能提供所有非const操作的替代实现(使它们甚至不会发出detach()的代码,这在某些容器中是非模板化的代码...)。鉴于Qt容器在过去几年中受到的关注很少,为什么不直接使用STD呢? - peppe
显示剩余2条评论

0

Qt 容器中缺少 STL 容器的几个特性。您可以在 Marc Mutz 的博客 这里 中找到它们的详细评估。

我认为,计划是用 qCopy 在构造函数中替换使用迭代器范围的功能,http://doc.qt.io/qt-4.8/qtalgorithms.html。在 Qt 5 中,许多容器的 iteratorconst_iterator 特性出现了,并且可能会在以后的版本中出现 QList 和 QVector 的适当构造函数(未公布,只是一种想法)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接