Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I would like to know if it is possible to obtain an iterator to an object inside a container (e.g. std::vector<...>) by only having access to the object inside the container, e.g. through a reference (which implies we have access to a pointer to it using the & operator). For example, normally we declare an iterator as

std::vector<int>::iterator = vec.begin();

or

std::vector<int>::iterator = next(vec.begin(), idx);

but in the first example we are most probably about to iterate through the container, in order, while in the second example we know the index of the object we require. I would like to know if we can obtain the iterator to an object without knowing at which index it resides in the container, but if we do have a reference or a pointer to it, as explained above.

It might appear that this question has already been asked here, but it seems more like the OP wanted others to fix his code, rather than answering the general question, so the answers are not so satisfactory in my opinion. Also, the answer here seems to say that we can initialize an iterator with a constructor, as shown below

std::vector<int>::iterator it(...);

but I have not been able to find any evidence of a constructor for the std::iterator class in the official documentation (and neither have I been able to find any documentation on std::vector<...>::iterator) so I am wary to use the constructor shown above, even if it compiles.

NOTE

I use std::vector as an example above, but ideally I would like this to work for any container, e.g. std::list or std::deque

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
342 views
Welcome To Ask or Share your Answers For Others

1 Answer

Specifically for std::vector (and other contiguous containers like std::string), given a pointer to an object in the vector p, we can simply do:

auto iter = v.begin() + std::distance(v.data(), p);

This is guaranteed by the contiguity contract. Note that random access is insufficient here, the above will not work for std::deque.

For any other container, there's no easy way of doing this. You'd have to just use find_if:

auto iter = std::find_if(c.begin(), c.end(), [p](auto const& o) { return &o == p; });

For intrusive containers, the iterator will be encoded into the object itself somehow so there will be some direct mechanism for converting p to an iterator. But that will be dependent on the intrusive container itself.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...