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

dan*_*ani 3 c++ iterator vector

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

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

vec.erase( find(crbegin(vec), crend(vec), value) ); //does not work
Run Code Online (Sandbox Code Playgroud)

编译器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> >}'
Run Code Online (Sandbox Code Playgroud)

如果我不使用反向迭代器,它可以工作(因此编译器注释):

vec.erase( find(cbegin(vec), cend(vec), value) ); //works
Run Code Online (Sandbox Code Playgroud)

如何判断它应该从头开始搜索value

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

BoB*_*ish 5

你不能告诉vector它用某种它不知道的迭代器擦除一个元素.你需要将反向迭代器重新转换为a std::vector::iterator.这样做std::reverse_iterator::base().但是,这会给你一个一个一个错误,因为反向迭代器必须做一些转换,以解释在范围的开头没有"结束"迭代器.使用std::prev考虑到这一点:

vec.erase(std::prev(find(crbegin(vec), crend(vec), value).base()));
Run Code Online (Sandbox Code Playgroud)

但请记住,这假设找到了元素.你的代码已经这样做,你的编辑说你故意这样做,所以我没有引入一个新问题,但实际上你应该在尝试擦除它之前检查元素.像(未经测试)的东西:

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()));
Run Code Online (Sandbox Code Playgroud)

  • `base()`会删除错误的元素,不是吗? (2认同)