【问题标题】:In C++, do iterator invalidation rules also apply to pointers for all the std containers?在C ++中,迭代器失效规则也适用于所有STD容器的指针?
【发布时间】:2017-04-11 07:03:00
【问题描述】:

我有一个包含一些元素的容器 C。在我的算法中,这些元素需要分成两个子组 C1 和 C2,它们将在其中进行排序。现在,为了避免两次存储相同的数据,这两个子组可以是

  1. std::sets of pointers 指向容器中的元素C,或
  2. std::sets of iterators 指向容器 C 中的元素。

我知道在遵循 Invalidation rules 时它可以很好地与迭代器一起使用,但是我只会使用 C1 和 C2 集来取消引用实际值并将 pointer/iterator 从 C1 移动到 C2 或相反,仅此而已。

从概念上讲,使用指针对我来说更有意义,但我不确定两件事:

使用指针真的可以为一些标准容器节省一些内存吗?(因为迭代器是指针的泛化)

Invalidation rules 是否也适用于所有标准容器的原始指针?

【问题讨论】:

  • 引用规则也适用于指针
  • 这些规则提到了“迭代器和引用”,其中也包括原始指针。为了回答您的第一个问题,在大多数情况下,迭代器和原始指针被编译成同一个东西,迭代器没有任何开销。我确信有一些“特殊情况”是例外,但在 98% 的情况下,您的编译器会将任何迭代器的开销优化为最终二进制文件中的简单指针算术。不添加这个作为答案,因为我相信有人会更专业地用 C++ 标准的链接和类似的东西来表达它,我懒得这样做:)
  • 因此,如果两种解决方案在内存方面是相同的(在 98% 的情况下),是否有任何理由先使用另一个?
  • 它们的语义确实略有不同,这就是为什么两者都是可行的选择。也许您必须与 C 库进行交互,您需要原始指针。或者,如果您使用 C++ 标准算法,迭代器会更方便。一个指导方针是不要将两者混合在一起说一个循环。如果你用迭代器循环,那么用迭代器循环。如果您使用原始指针,请使用它。但是如果你混合访问元素的方式,你会让你的编译器很难优化你的代码。

标签: c++ c++11 pointers iterator std


【解决方案1】:

使用指针真的可以为一些标准容器节省一些内存吗?

从我的角度来看,我认为指针的成本总是小于或等于迭代器。当你使用指针时,它会花费你一个指针。虽然迭代器实现因实现而异,但它必须有一些方法来引用原始容器,这将花费您一个指针或一个引用,在最好的情况下,这将花费您与指针一样多的成本。而this test 似乎支持我。

无效规则是否也适用于所有标准容器的原始指针?

来自C++ FAQ:

重要提示:尽管在底层汇编语言中通常使用地址来实现引用,但请不要将引用视为指向对象的有趣指针。引用是对象。它不是指向对象的指针,也不是对象的副本。 就是对象。

那么,那些不会使your linked question 中的引用无效的容器上的任何操作都不会使指针无效,即使该操作使迭代器无效,unordered_[multi]{set,map} 插入就是这种情况。

【讨论】:

  • 取决于我们谈论的容器类型。有些容器会使某个操作的所有内容失效,有些则不会。
  • @adam10603 所有无效规则都包含在该链接问题中,我只回答了参考规则也适用于指针的一般规则。如果引用不受影响,对象不受影响,指向该对象的指针应该仍然有效
  • @Danh 你也可以回答第一个问题吗? (关于记忆)
  • @Riko 我为你的第一个问题添加了答案
猜你喜欢
  • 2017-10-05
  • 2022-10-20
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
  • 2011-09-20
相关资源
最近更新 更多