std::vector 在最后一个之后用第一个迭代器擦除
std::vector erasing with first iterator after last
擦除第一个迭代器在最后一个迭代器之后的范围时会发生什么?
std::vector<int> v{1,2};
v.erase(
v.begin() + 1,
v.begin()
);
其他容器呢?
在任何容器上使用无效范围调用 erase
是 未定义行为。在实践中,它通常会导致程序崩溃如果你幸运,或者如果你不幸运
会粉碎相邻内存。
这对于接受迭代器范围的几乎 any API 应该是正确的。如果范围无效,则底层 code/algorithm 无法知道实际停止条件是什么。
迭代器范围界定任何输入或算法范围的开始和结束。 end
迭代器始终用于指示该范围的完成,并且必须始终可以通过重复递增第一个迭代器(例如通过调用 operator++
)来访问。
大多数算法利用 operator!=
来检测范围的完成,从 LegacyInputIterator
requirement. Some ranges may optionally make use of the distance between iterators if that that range is a LegacyRandomAccessIterator
.
无论哪种情况,此检测要求第一个迭代器在最后一个迭代器之前,否则代码如下:
for (auto it = first; first != last; ++first) { ... }
永远不会到达范围的末尾,同样:
auto distance = last - first;
将 return 迭代器之间的距离值不正确。
擦除第一个迭代器在最后一个迭代器之后的范围时会发生什么?
std::vector<int> v{1,2};
v.erase(
v.begin() + 1,
v.begin()
);
其他容器呢?
在任何容器上使用无效范围调用 erase
是 未定义行为。在实践中,它通常会导致程序崩溃如果你幸运,或者如果你不幸运
这对于接受迭代器范围的几乎 any API 应该是正确的。如果范围无效,则底层 code/algorithm 无法知道实际停止条件是什么。
迭代器范围界定任何输入或算法范围的开始和结束。 end
迭代器始终用于指示该范围的完成,并且必须始终可以通过重复递增第一个迭代器(例如通过调用 operator++
)来访问。
大多数算法利用 operator!=
来检测范围的完成,从 LegacyInputIterator
requirement. Some ranges may optionally make use of the distance between iterators if that that range is a LegacyRandomAccessIterator
.
无论哪种情况,此检测要求第一个迭代器在最后一个迭代器之前,否则代码如下:
for (auto it = first; first != last; ++first) { ... }
永远不会到达范围的末尾,同样:
auto distance = last - first;
将 return 迭代器之间的距离值不正确。