如何解决无效的迭代器:在不降低效率的情况下使用 UB 修复函数
考虑以下函数:
template<class T>
void remove_unordered(std::vector<T>& vec,T const& val)
{
auto it = begin(vec);
while (it != end(vec)) {
if (*it == val) {
*it = std::move(vec.back());
vec.pop_back();
}
else { ++it; }
}
}
问题是当 it
指向最后一个元素并且该元素被删除时。这使迭代器无效,因此这是 UB。它应该正常工作,因为迭代器实际上是结束。
Can you pop_back a vector and still use the iterator to the last element? 基本上问了同样的问题。答案并没有以效率低得多的方式修复该功能。所以我还在想有没有更好的方法可以不用UB。
解决方法
以下应该是一种可能的解决方法,尽管它看起来不太好并且几乎没有额外的工作:
template<class T>
void remove_unordered(std::vector<T>& vec,T const& val)
{
if(vec.empty()) { return; }
auto it = begin(vec);
while (it+1 != end(vec)) {
if (*it == val) {
*it = std::move(vec.back());
vec.pop_back();
}
else { ++it; }
}
if (*it == val) {
vec.pop_back();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。