首页 文章

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

提问于
浏览
3

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

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

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 回答

  • 5

    你不能告诉 vector 用某种它不知道的迭代器来擦除一个元素 . 您需要将反向迭代器重新转换为 std::vector::iterator . 使用std::reverse_iterator::base()执行此操作 . 但是,这会给你一个一个一个错误,因为反向迭代器必须做一些转移,以解释在范围的开头没有"end"迭代器 . 使用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()));
    

相关问题