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
The most obvious form of an iterator is a pointer. A pointer can point to elements in an array and can iterate through them using the increment operator (++). But, all iterators do not have similar functionality as that of pointers.
An iterator is an object (like a pointer) that points to an element inside the container. We can use iterators to move through the contents of the container. They can be visualised as something similar to a pointer pointing to some location and we can access content at that particular location using them.
You could pass a const reference, but usually iterators are small enough that it gives no advantage over passing by value.
Iterators is a generic concept. They work on all sorts of containers and have similar interface. Accessing the array element directly like arr_int[i] is definitely faster because it directly translates to pointer arithmetic.
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.
You can use the find
function---it returns an iterator---, supported on (almost?) all containers, to find your objects. If there are several objects which are equal under the operator==
, iterate until the one with the same address has been found.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With