通过索引访问向量迭代器?
Accessing a vector iterator by index?
最近我在我的代码库中看到了这段代码(当然这里已经简化了)
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;
还是未定义行为?
来自 cppreference documentation 的 RandomAccessIterator:
Expression: i[n]
Operational semantics: *(i+n)
由于astd::vector
的迭代器满足RandomAccessIterator的要求,索引它们相当于加法和解引用,就像一个普通的指针。 iter[0]
等同于 *(iter+0)
,或 *iter
。
这是 Standard 合规行为
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)
请注意,不 要求将特定迭代器实现为指针。任何具有重载 operator[]
、operator*
和 operator+
并具有上述语义的迭代器 class 都可以工作。对于std::vector
,迭代器类别是随机访问迭代器,它需要才能工作。
最近我在我的代码库中看到了这段代码(当然这里已经简化了)
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;
还是未定义行为?
来自 cppreference documentation 的 RandomAccessIterator:
Expression:
i[n]
Operational semantics:
*(i+n)
由于astd::vector
的迭代器满足RandomAccessIterator的要求,索引它们相当于加法和解引用,就像一个普通的指针。 iter[0]
等同于 *(iter+0)
,或 *iter
。
这是 Standard 合规行为
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)
请注意,不 要求将特定迭代器实现为指针。任何具有重载 operator[]
、operator*
和 operator+
并具有上述语义的迭代器 class 都可以工作。对于std::vector
,迭代器类别是随机访问迭代器,它需要才能工作。