使用`vec.erase(find(...))删除元素`如果`find`应该开始以崇敬的顺序搜索

时间:2016-02-27 19:33:51

标签: c++ vector iterator

我有一个唯一(!)元素的向量,想要删除一个具有特定值的元素。这个元素也很可能接近向量的末尾。因此,我想从头开始寻找这个元素。

我认为这应该有效,但事实并非如此。

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

编辑:我知道,该向量包含搜索到的元素。

1 个答案:

答案 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()));