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

时间:2016-04-29 20:23:05

标签: c++ c++11 iterator dereference random-access

最近我在我的代码库中遇到了这段代码(当然是简化版)

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

现在,我注意到我们在这里通过索引来访问迭代器!

std::shared_ptr<std::string> deletedString = iter[0];

我以前从未见过有人通过索引访问迭代器,所以我所能猜到的是迭代器被视为指针,然后我们访问指向指针的第一个元素。那么代码实际上等同于:

std::shared_ptr<std::string> deletedString = *iter;

或者是未定义的行为?

2 个答案:

答案 0 :(得分:5)

来自RandomAccessIterator的cppreference documentation

  

表达式:i[n]

     

操作语义:*(i+n)

由于std::vector的迭代器满足RandomAccessIterator的要求,因此索引它们等同于添加和解除引用,就像普通指针一样。 iter[0]相当于*(iter+0)*iter

答案 1 :(得分:4)

符合行为的Standard

  

24.2.7随机访问迭代器[random.access.iterators]

     

1类或指针类型X满足随机访问迭代器的要求   如果,除了满足双向的要求   迭代器,以下表达式有效,如表118所示。

     

a[n]可转换为参考:*(a + n)

请注意,特定迭代器实现为指针是。具有上述语义的重载operator[]operator*operator+的任何迭代器类都将起作用。对于std::vector,迭代器类别是随机访问迭代器,必需可以工作。