C++ QMap/QHash运算符[]返回了引用有效性

C++ QMap/QHash运算符[]返回了引用有效性,c++,qt,dictionary,qmap,C++,Qt,Dictionary,Qmap,我想知道对Qt容器中的值的引用,特别是QHash或QMap的引用有效多长时间。我所说的valid是指在插入或删除其他元素后,它仍然指向map/hash中的正确位置 让我们看看下面的代码: QHash<char,int> dict; // or QMap<char,int> dict; dict.insert('a', 1); int& val(dict['a']); dict.insert('b', 2); val = 3; // &l

我想知道对Qt容器中的值的引用,特别是
QHash
QMap
的引用有效多长时间。我所说的valid是指在插入或删除其他元素后,它仍然指向map/hash中的正确位置

让我们看看下面的代码:

QHash<char,int> dict; // or QMap<char,int> dict;
dict.insert('a', 1);
int& val(dict['a']);

dict.insert('b', 2);

val = 3;             // < will this work or lead to a segfault
QHash dict;//或QMap dict;
插入指令(“a”,1);
int&val(dict['a']);
插入命令('b',2);
val=3;//<这会起作用还是导致SEG故障

在最后一行设置值是否会正确地将与
a
关联的值更新为
3
,或者是否会导致segfault或它是否未定义(因此有时工作,有时segfault,取决于是否必须在内部重新组织数据结构,如调整哈希表数组的大小)。
QMap
QHash
的行为是否相同,或者一个有效,另一个无效?

除非删除正在引用的节点,否则在QMap/QHash元素中使用引用没有错。qt容器的元素不会在每次插入新元素时重新分配。但是,我看不到使用容器元素引用的任何好理由

有关更多详细信息,请查看这篇关于

的优秀文章,这篇文章已在中全面介绍-您一定错过了

当容器中的数据丢失时,这两种类型的迭代器都将失效 由于调用而被修改或从隐式共享副本中分离 非常量成员函数

因此,尽管我希望迭代器/引用在您上面描述的场景中在实践中保持有效,但您不应依赖于此以这种方式使用它们将调用未定义的行为。


这适用于
QHashIterator
QMutableHashIterator
,以及裸引用。当心声称相反的非权威引用,依赖于可能随时更改的实现细节。

我确实错过了这一点,因为它谈论的是迭代器而不是引用。因此,尽管迭代器不再有效,引用仍然有效,但这似乎不太可能。@inflagranti:迭代器无效规则也普遍应用于元素的引用。这是因为迭代器会取消对引用的引用,如果您不能再取消对迭代器的引用以获得引用,那么从该迭代器获得的任何引用也将不再有效。@TomalakGeret'kal您真的确定吗?例如,如果散列或映射节点确实分配了堆上的值并引用了带有指针的值,则散列的重组显然会使迭代器(基本上是指向节点的指针)无效,但是引用的值可能仍然完全未被触及。事实上,如果w.r.t.不复制周围的数据,这将非常有意义。所以,我不太确定迭代器->引用泛化。关于这一点没有任何声明。@TomalakGeret'kal:当然,但它没有提到这个问题。您之前将语句“迭代器失效”泛化为“指向存储在迭代器上的对象的指针失效”。我认为,这种概括在一般情况下是无效的。参考Weblectic答案中的链接,您将在QList中看到一个示例,其中对于大对象,对象确实在堆上分配,并从指针列表引用。指针可能会在指针列表中移动,从而导致指向该列表的迭代器无效。然而,指针是固定不变的。@TomalakGeret'kal:好的,我们有点同意。我仍然认为,严格地说,任何关于迭代器是否被保留的声明,都不能说明指向elments的指针,因为即使迭代器保持有效,理论上也可能存在迭代器在幕后被更新或者值存储被重新排序(垃圾收集?)的情况因此,指向元素的指针会悬空。我只是希望他们能保证指向接口的指针,因为它在技术上似乎存在(对于大型元素),并且在某些情况下非常有用。使用引用的原因是,这样就不需要再次在字典中锁定来更改值(如果值是结构,这尤其有用).谢谢你的链接!但是,请注意,引用/指针的稳定性确实是复杂的:例如,对于QList,实现细节使QList的行为使得指向元素的指针实际上是稳定的。但是,指向QList或QList中元素的指针是/不/稳定的,因为它们存储在主列表中,而不是在堆上分配。本质上,接口中没有声明/保证。