【问题标题】:Finding the owner of an STL iterator查找 STL 迭代器的所有者
【发布时间】:2010-09-27 09:32:38
【问题描述】:

有什么方法可以找到迭代器指向的容器?具体来说,我希望能够找到特定std::vector::iterator 指向的std::vector,这样我就可以检查范围,而不必实际传递对该向量的引用。

如果(我怀疑)答案是否定的,为什么不呢?

编辑:感谢您提供一些快速且(大部分)准确的答案。 Evan Teran 搞定了。我根本没有考虑优化,但现在很明显。

有几个人问我想这样做是为了什么。这没什么特别重要的。我有一个用向量和指向向量的迭代器初始化的对象。如果我可以只使用迭代器来初始化对象,那将是可爱和方便的,因为这样我就可以将vector::iterators 直接转换为这个对象(这听起来很奇怪,但在特定情况下确实有意义)。但这一点都不重要。

【问题讨论】:

    标签: c++ stl iterator


    【解决方案1】:

    我不相信。如果迭代器必须保留指向其所属容器的引用/指针,那么就不可能将它们优化为轻量级指针(这可以通过容器保证连续存储,如向量等来完成)。

    【讨论】:

      【解决方案2】:

      没有办法让它工作。原因很简单:向迭代器添加一种方法来获取它们所指向的容器是

      • 毫无意义。迭代器对集合进行迭代。正如其他人所说,仅此而已。
      • 与迭代器要求不兼容。请记住,指针是随机访问迭代器。将容器指针放入迭代器对算法没有用处,因为它们是通用的,与特定的迭代器实现分离。用作迭代器的指针不能有指向作为成员的数组的指针。

      你说你需要它来进行范围检查。您可以提供一个结束迭代器,它指向范围的最后一个有效迭代器位置之后的位置。检查您当前的位置是否不在末尾。这就是范围检查所需要做的一切。

      【讨论】:

        【解决方案3】:

        您不能以一般方式从迭代器中检索容器。举个例子,为什么可以使用普通指针作为迭代器:

        #include <algorithm>
        #include <cstdio>
        #include <cstring>
        
        int
        main(int argc, char *argv[])
        {
                const char s[] = "Hello, world!";
                const char *begin = s;
                const char *end = s + strlen(s);
        
                std::for_each(begin, end, putchar);
        
                return 0;
        }
        

        如何从指针中检索原始字符串(如果它没有指向字符串的开头)?

        但是,如果您需要此功能,那么您始终可以implement 您自己的包装器围绕存储对容器的引用的迭代器。

        【讨论】:

        • 用一个具体而简单的例子说明了为什么不能从迭代中获取容器...
        • 但这并不是真正的原因,原因很大程度上是哲学上的。然而,它确实说明了一个技术/设计问题,如果迭代器被假设为其他东西,就会出现这种问题。
        【解决方案4】:

        理论上,如果所讨论的迭代器至少是前向迭代器,则有一种方法。您可以检查您的迭代器是否是每个候选容器的 [first,last) 中的迭代器之一。由于您使用的是向量容器,因此您有一个随机访问迭代器,您可以使用小于运算符快速执行此检查。

        您必须事先了解所有要检查的候选向量, 这不是获取迭代器所属容器的通用方法。

        但是,您可以通过使用包含指向创建向量的指针的东西来装饰随机访问迭代器来定义随机访问迭代器的扩展。这可能有点不优雅、低效和不方便。所以先看看你是否可以重写代码来避免这种需要。

        【讨论】:

        • 第一个建议绝对依赖于未说明的实现细节,并且维护起来会非常麻烦。我宁愿实现装饰器;至少这样可以保证它始终有效并使我的意图显而易见。
        • 不正确。第一个建议取决于官方支持的能力相等检查迭代器,或者官方支持的
        • 我想收回我之前的评论,但我要把它留给后代。事实上,该解决方案确实需要依赖随机访问迭代器,这些迭代器基本上被实现为指针或类似指针的东西,涉及地址空间中的位置(根据“地址空间”的技术定义)。如果您比较来自不同容器的随机访问迭代器,我看不到一个干净、标准化的定义。
        【解决方案5】:

        STL 不允许这样做。

        例如,Vecor 迭代器可以简单地实现为指针。并且没有通用的方法可以从指向对象已分配的某些数据的指针中检索对象。

        【讨论】:

          【解决方案6】:

          我不相信有一种公开的方法可以做到这一点。原因是,这不是迭代器的目的。当然,迭代器不能持有指向其父容器的指针没有技术原因。即使它以不需要该指针的方式实现,它仍然可以保存它。

          迭代器旨在对集合进行迭代,因此,它们提供了执行此操作所必需的接口,并且仅此而已。这是很好的面向对象编程原则。

          请问您的用例是什么,您需要知道带有迭代器的容器的“范围”吗?

          【讨论】:

            【解决方案7】:

            如前所述,最好重写您的代码,这样您就不需要这种行为了。这就像拿着硬币一样,但你不知道它是从哪里来的,除非你在纸上注明。

            如果您无法重写代码,您仍然可以引入一个包含指向容器和迭代器本身的指针的包装对象。你具体需要这个做什么?

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2015-07-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-03-16
              • 2012-07-20
              相关资源
              最近更新 更多