Recently I came across this code in my codebase (Simplified for here, of course)
auto toDelete = std::make_shared<std::string>("FooBar");
std::vector<decltype(toDelete)> myVec{toDelete};
auto iter = std::find_if(std::begin(myVec), std::end(myVec),
[](const decltype(toDelete) _next)
{
return *_next == "FooBar";
});
if (iter != std::end(myVec))
{
std::shared_ptr<std::string> deletedString = iter[0];
std::cout << *deletedString;
myVec.erase(iter);
}
Now, I noticed that here we are accessing an iterator by indexing!
std::shared_ptr<std::string> deletedString = iter[0];
I've never seen anyone access an iterator by indexing before, so all I can guess at is that the iterator gets treated like a pointer, and then we access the first element pointed to at the pointer. So is that code actually equivalent to:
std::shared_ptr<std::string> deletedString = *iter;
Or is it Undefined Behavior?
From the cppreference documentation for RandomAccessIterator:
Expression:
i[n]
Operational semantics:
*(i+n)
Since a std::vector
's iterators meet the requirements of RandomAccessIterator, indexing them is equivalent to addition and dereferencing, like an ordinary pointer. iter[0]
is equivalent to *(iter+0)
, or *iter
.
This is Standard conforming behavior
24.2.7 Random access iterators [random.access.iterators]
1 A class or pointer type X satisfies the requirements of a random access iterator if, in addition to satisfying the requirements for bidirectional iterators, the following expressions are valid as shown in Table 118.
a[n]
convertible to reference:*(a + n)
Note that it is not required that the particular iterator is implemented as a pointer. Any iterator class with an overloaded operator[]
, operator*
and operator+
with the above semantics will work. For std::vector
, the iterator category is random access iterator, and it it required to work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.