查找 STL 迭代器的所有者

发布于 2024-07-10 06:45:09 字数 532 浏览 4 评论 0原文

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

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

编辑:感谢您提供一些快速且(很大程度上)准确的答案。 Evan Teran 解决了这个问题。 我根本没有考虑优化,但现在很明显了。

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

Is there any way that I can find the container pointed to by an iterator? Specifically, I want to be able to find the std::vector pointed to by a particular std::vector::iterator so that I can check the range, without having to actually pass references to that vector around.

If (as I suspect) the answer is no, why not?

edit: thanks for a number of quick and (largely) accurate answers. Evan Teran nails it. I wasn't thinking about optimization at all, but it's obvious now.

A couple of people asked what I want to do this for. It's nothing terribly important. I have an object which is initialized with a vector and an iterator pointing into the vector. It would be cute and convenient if I could initialize the object just with an iterator because then I could convert vector::iterators directly to this object (this sounds strange but does make sense in the particular case). But it's not crucial at all.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

三生殊途 2024-07-17 06:45:09

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

I don't believe so. If iterators had to keep a reference/pointer to their owning container, then it would be impossible for them to be optimized down to a lightweight pointer (which can be done with containers guaranteeing contiguous storage like vectors and such).

柳若烟 2024-07-17 06:45:09

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

  • 没有意义的。 迭代器迭代集合。 正如其他人所说,仅此而已,仅此而已。
  • 与迭代器要求不兼容。 请记住,指针是一个随机访问迭代器。 将容器指针放入迭代器对于算法来说是没有用的,因为它们是通用的,与特定迭代器实现解耦。 用作迭代器的指针不能有返回到作为成员从中获取的数组的指针。

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

There is no way to make that work. The reason is simple: Adding a way to the iterators to get the container to which they are pointing is

  • Pointless. Iterators iterate over a collection. As other said, only that, nothing more.
  • Not compatible with the iterator requirements. Remember a pointer is a random access iterator. Putting a container pointer into the iterator would be of no use for algorithms, since they intend to be generic, decoupled from specific iterator implementations. A pointer used as an iterator can't have a pointer back to the array it was taken from as a member.

You say you need it for range checking. You can provide an end iterator which points one after the last valid iterator position of a range. Check whether your current position is not at the end. That is all you need to do for range checking.

凤舞天涯 2024-07-17 06:45:09

您无法以一般方式从迭代器检索容器。 举个例子来说明原因,普通指针可以用作迭代器:

#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;
}

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

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

You cannot retrieve the container from an iterator in a general way. As an example of why, a plain pointer can be used as an iterator:

#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;
}

How could you retrieve the original string from a pointer (if it isn't pointed at the beginning of the string)?

However, if you need this functionality then you could always implement your own wrapper around the iterator that stores a reference to the container.

吃兔兔 2024-07-17 06:45:09

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

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

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

In theory there's a way if the iterator in question is at least a forward iterator. You can check whether your iterator is one of the iterators in [first,last) for each candidate container. Since you're using a vector container, you have a random access iterator, you can use the less-than operator to do this check quickly.

You DO have to know all of the candidate vectors against which to check up front,
and this is not a general way to get the container to which an iterator belongs.

You can, however, define an extension of random access iterators by decorating random access iterator with something containing a pointer to the creating vector. This is likely to be slightly inelegant, inefficient, and inconvenient. So see if you can rewrite code to avoid this need first.

冷心人i 2024-07-17 06:45:09

STL 不允许这样做。

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

The STL does not allow for this.

Vecor iterators, for example, may be implemented simply as a pointer. And there is no general way to retrieve an object from a pointer pointing to some data the object has allocated.

摇划花蜜的午后 2024-07-17 06:45:09

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

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

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

I don't believe there's an exposed method to do that. The reason being, that's not the purpose of the iterator. There is, of course, no technical reason that an iterator could not hold a pointer to its parent container. Even if it is implemented in such a way that does not require that pointer, it could still hold it.

Iterators are intended to iterate over the collection, and as such, they provide the interface necessary to do that and only that. This is good object-oriented programming principles.

May I ask what your use-case is, that you need to know the "range" of the container with an iterator?

鼻尖触碰 2024-07-17 06:45:09

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

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

As suggested earlier it is best to rewrite your code so that you don't need this behavior. It is the same as holding a coin, but you have no idea where it comes from unless you noted that down on a paper.

If you are unable to rewrite the code you could still introduce a wrapping object that contains a pointer to the container and the iterator itself. What do you need this for specifically?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文