【问题标题】:What effect does "insert" have on references to deques?“插入”对双端队列的引用有什么影响?
【发布时间】:2017-05-31 22:44:43
【问题描述】:

我在我的一个 C++ 程序中使用了 deque,并且正在 cppreference.com 上阅读 insert 的文档。除了这一点之外,大部分都是有意义的:

所有迭代器,包括过去的迭代器,都无效。 引用也无效,除非pos == begin()pos == end(), 在这种情况下,它们不会失效。

这是什么意思?这是说对双端队列本身的引用无效,还是对其元素的引用,或对迭代器的引用?还是完全不同的东西?

这是相关文档的链接:http://en.cppreference.com/w/cpp/container/deque/insert

【问题讨论】:

  • 对元素的引用。
  • @BaummitAugen 这怎么可能? C++ 引用一旦分配就不能更改。
  • 好的,但如果它只是内存块,那么为什么“插入”会使迭代器无效到开始/结束? @BaummitAugen
  • 它通过将元素移向更接近的开头或结尾来在插入点创建一个空间。如果需要一个新的开始或结束块,则创建一个。这将使开始/结束迭代器无效。

标签: c++ deque


【解决方案1】:

deque 是一个对象。它是一个容器,因此它在其内部存储中包含 other 对象。这些是存储在deque 中的元素。

您可以访问这些元素。访问元素基本上是从容器中获取 reference。如果你检查它,element access 部分下的所有方法都返回一个reference 类型。

您可以制作访问元素的副本,但您可以存储引用本身。 T foo = d.front();T& bar = d.front();(让d 成为一些std::deque<T>

对双端队列的引用是auto& ref_d = &d;。这是另一回事。

所以:

1. “插入”对双端队列的引用有什么影响?

没有。对d 的引用很好。

2。这是什么意思?

双端队列的设计方式是在开头或结尾插入不会使对您可能已经存储的元素的引用无效。虽然如果你在中间插入,元素可能会在内存中移动。请注意,bar 没有被触及。正是因为它不可能,所以它变得无效。 先前获得的引用(或迭代器)不再指向任何有意义的东西,因此取消引用是非法的。

3.这是说对双端队列本身的引用无效吗?

不,和 1 一样。

4.或对其元素的引用[无效]?

是的,就像在 2 中一样。

5.或对迭代器的引用[无效]?

你似乎又混淆了什么是什么。如果您从deque 获得迭代器,则对迭代器的引用将是std::deque<T>::iterator& iter_ref;。例如。 auto iter = d.begin(); 并引用它 iter_ref = &iter;insert 不会使 *iter_ref 非法,它会使迭代器无效,因此 *iter 是非法的(或 **ref_iter)。

注意:我并不是说像 std::deque<T>& ref_dstd::deque<T>::iterator& iter_ref 这样的东西有意义,但这是“引用双端队列”和“引用交互器”的语义含义。

【讨论】:

  • 所以,如果我理解正确...如果您在除前端或末端以外的任何位置调用插入,则迭代器可能会失效,但在前端或末端插入会保留迭代器?
  • 没错。这就是您的引用所说的:“所有迭代器,包括过去的迭代器,都已失效。引用也失效,除非pos == begin()pos == end(),在这种情况下它们不会失效。 i>”由于某种原因,您刚刚在您的问题中提出了“对双端队列的引用”和“对迭代器的引用”的附加术语,并且感到困惑。
  • 但是对在调用insert 之前创建的元素的任何引用仍然应该是有效的引用,对吗?
  • @Dovahkiin。不会。一旦insert 导致元素被移动,所有赌注都将被取消。这些引用可能指的是同一个地方,但它们也可能指的是deque 中的错误元素,deque 的旧数据存储的一部分尚未重用的剩余部分,另一个位于@ 空间中的数据结构987654348@ 的数据存储以前被占用,没有,或者介于两者之间。虽然您可以进行猜测,但您无法从一般意义上知道。假设它们都是定时炸弹,等待引爆你的程序并摆脱它们。
猜你喜欢
  • 1970-01-01
  • 2020-04-19
  • 2020-11-08
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 2013-11-13
相关资源
最近更新 更多