我有一个唯一(!)元素的向量,想要删除一个具有特定值的元素。这个元素也很可能接近向量的末尾。因此,我想从头开始寻找这个元素。
我认为这应该有效,但事实并非如此。
vec.erase( find(crbegin(vec), crend(vec), value) ); //does not work
编译器sais(缩短):
error: no matching function for call to 'std::vector<unsigned int>::erase(std::reverse_iterator<__gnu_cxx::__normal_iterator<unsigned int*, std::vector<unsigned int> > >)'
and also
note: no known conversion for argument 1 from 'std::reverse_iterator<__gnu_cxx::__normal_iterator<unsigned int*, std::vector<unsigned int> > >' to 'std::vector<unsigned int>::const_iterator {aka __gnu_cxx::__normal_iterator<const unsigned int*, std::vector<unsigned int> >}'
如果我不使用反向迭代器,它可以工作(因此编译器注释):
vec.erase( find(cbegin(vec), cend(vec), value) ); //works
如何判断它应该从头开始搜索value
?
编辑:我知道,该向量包含搜索到的元素。
答案 0 :(得分:5)
你不能告诉vector
用某种它不知道的迭代器来擦除一个元素。您需要将反向迭代器重新转换为std::vector::iterator
。使用std::reverse_iterator::base()
执行此操作。但是,这会给你一个一个一个错误,因为反向迭代器必须做一些转移,以解释没有&#34;结束&#34;范围开头的迭代器。使用std::prev
来说明这一点:
vec.erase(std::prev(find(crbegin(vec), crend(vec), value).base()));
请记住,这假定找到了该元素。你的代码已经这样做了,你的编辑说你故意这样做,所以我没有引入新的问题,但实际上你应该在尝试擦除它之前检查元素。像(未经测试)的东西:
auto foundCRIt = std::find(std::crbegin(vec), std::crend(vec), value);
if (foundCRIt == std::crend(vec)) {
std::cerr << "Not found!\n";
return;
}
vec.erase(std::prev(foundCRIt.base()));