7

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

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

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

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

4

7 回答 7

8

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

于 2008-12-17T18:48:48.660 回答
5

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

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

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

于 2008-12-17T19:21:27.940 回答
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;
}

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

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

于 2008-12-17T18:56:24.790 回答
2

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

您必须知道要预先检查的所有候选向量,这不是获取迭代器所属容器的一般方法。

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

于 2008-12-17T18:58:21.543 回答
1

STL 不允许这样做。

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

于 2008-12-17T19:09:07.153 回答
0

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

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

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

于 2008-12-17T18:54:53.907 回答
0

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

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

于 2008-12-17T19:16:35.233 回答