Finding the owner of an STL iterator

Is there a way to find the container that the iterator points to? In particular, I want to find std :: vector that a particular std :: vector :: iterator points to so that I can check the range without having to actually pass references to this vector.

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

edit: thanks for a series of quick and (mostly) accurate answers. Evan Teran nails him. I did not think about optimization at all, but now it is obvious.

Several people asked why I want to do this. This is nothing to worry about. I have an object that is initialized with a vector and an iterator pointing to the vector. It would be nice and convenient if I could only initialize the object using an iterator, because then I could convert vector :: iterators directly to this object (this sounds strange, but it makes sense in a particular case). But this is not critical.

+6
c ++ iterator stl
source share
7 answers

I don’t believe that. If iterators were supposed to contain a link / pointer to the owner, then it would be impossible to optimize them to a light weight pointer (which can be done with containers that guarantee continuous storage, such as vectors, etc.).

+6
source share

Unable to do this job. The reason is simple: adding a path to iterators to get the container they point to

  • It makes no sense. Iterators iterate over the collection. As the other said, only this, nothing more.
  • Not compatible with iterator requirements. Remember that a pointer is a random access iterator. Placing a container pointer in an iterator would be useless for the algorithms, since they intend to be universal, separate from specific implementations of the iterator. A pointer used as an iterator cannot have a pointer back to the array from which it was taken from a member.

You say you need this to test the range. You can provide a final iterator that points one after the last valid position of the range iterator. Check if the current position is at the end. This is all you need to do to check the range.

+4
source share

You cannot retrieve a container from an iterator in a general way. As an example, a simple 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 extract the original line from the pointer (if it is not indicated at the beginning of the line)?

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

+3
source share

In theory, there is a way if the considered iterator is at least the front iterator. You can check if your iterator is one of the iterators in the [first, last] for each candidate container. Since you are using a vector container, you have a random access iterator, you can use a smaller operator to quickly perform this check.

You need to know all the candidate vectors with which you need to check the front, and this is not a general way to get the container to which the iterator belongs.

However, you can define the extension of random access iterators by decorating a random access iterator with something containing a pointer to the creating vector. It will probably be a little inelegant, inefficient and uncomfortable. See if you can rewrite the code to avoid this need.

+2
source share

STL does not allow this.

Vecor iterators, for example, can be implemented simply as a pointer. And there is no general way to retrieve an object from a pointer that points to some of the data allocated by the object.

+1
source share

I do not believe that there is an open method for this. The reason is that it is not the goal of the iterator. Of course, there is no technical reason for the iterator to not be able to hold the pointer to its parent container. Even if it is implemented in a way that does not require this pointer, it can still hold it.

Iterators are designed to iterate over a collection, and therefore they provide the interface necessary for this, and only that. These are good principles for object-oriented programming.

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

0
source share

As suggested earlier, it’s best to rewrite your code so that you don’t have this behavior. It’s the same as holding a coin, but you don’t know where it came from unless you marked it on paper.

If you cannot rewrite the code, you can still enter a wrapper object containing a pointer to the container and the iterator itself. Why do you need this?

0
source share

All Articles