微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无效的迭代器:在不降低效率的情况下使用 UB 修复函数

如何解决无效的迭代器:在不降低效率的情况下使用 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 举报,一经查实,本站将立刻删除。