最近我在我的代码库中遇到了这段代码(当然是简化版)
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);
}
现在,我注意到我们在这里通过索引来访问迭代器!
std::shared_ptr<std::string> deletedString = iter[0];
我以前从未见过有人通过索引访问迭代器,所以我所能猜到的是迭代器被视为指针,然后我们访问指向指针的第一个元素。那么代码实际上等同于:
std::shared_ptr<std::string> deletedString = *iter;
或者是未定义的行为?
答案 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
,迭代器类别是随机访问迭代器,必需可以工作。