简体   繁体   English

通过索引访问矢量迭代器?

[英]Accessing a vector iterator by index?

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

Online Example 在线示例

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: 从RandomAccessIterator的cppreference文档

Expression: i[n] 表达: i[n]

Operational semantics: *(i+n) 操作语义: *(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. 由于std::vector的迭代器满足RandomAccessIterator的要求,因此索引它们等同于添加和解除引用,就像普通指针一样。 iter[0] is equivalent to *(iter+0) , or *iter . iter[0]相当于*(iter+0)*iter

This is Standard conforming behavior 这是标准符合行为

24.2.7 Random access iterators [random.access.iterators] 24.2.7随机访问迭代器[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. 1类或指针类型X满足随机访问迭代器的要求,除了满足双向迭代器的要求之外,以下表达式有效,如表118所示。

a[n] convertible to reference: *(a + n) a[n]可转换为参考: *(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. 具有重载operator[]operator*operator+以及上述语义的任何迭代器类都可以工作。 For std::vector , the iterator category is random access iterator, and it it required to work. 对于std::vector ,迭代器类别是随机访问迭代器,它需要工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM