我想再问这个问题,尽管Why do Qt's container classes not allow movable, non-copyable element types?。我已经阅读了QtCore维护者Thiago的以下声明(链接来自链接的Stackoverflow问题的答案):
永远不会实施。由于隐式共享,可复制性是强制性要求。
我不明白这句话:可复制性 是隐式共享的强制要求,我理解这一部分。但为什么隐式共享是不可复制的QList<T>
的要求?
QList
已经有移动构造函数和移动赋值运算符,所以假设从另一个临时QList<T>
构造QList<T>
将不会应用隐式共享,而是移动基础d-指针,在什么情况下只会复制/分配临时/右值QList
时会出现隐式共享?
答案 0 :(得分:0)
可能是因为QLists仅标记为可重入,但不是线程安全的(definition)。
我没有查看源代码,但是猜测维护线程安全QList的开销超过支持普通用户的成本(当然这只是假借口:P)。
当T是指针或引用时,它可能意味着在更改列表中的对象时必须同步多个内存空间 - 这似乎超出了Qt框架的范围。我还可以想象,如果主线程中有一些工厂实例化对象,Qt会变得复杂。或者当一个对象拥有线程或回调的引用/指针时。
可能不应该回答您的任何问题,但这比评论更长。
答案 1 :(得分:0)
隐式共享所有Qt容器类。这不是可以谈判的东西。您还希望通过值发出QList的信号连接到多个插槽吗?如果没有移动语义或没有隐式共享,你就会得到大量的副本。使用移动语义,除第一个插槽之外的所有插槽都将获得一个空的(好的,未指定的移动)列表。因此,隐含共享在其他API细节的情况下变得必不可少,因为它们的价值太多了,因为它们为什么不呢?无论如何,一切都是隐含的。
总结一下:我不认为Qt想要对其任何容器的实现做出例外,例如使一个移动列表没有隐式共享,而任何其他列表都会有这种隐式共享。副作用的差异太大了。
另请注意,至少在读取行之间时,它们更倾向于std容器,尽管API中出现的那些将比任何人想要的更多......