使用'find'或'remove'中的迭代器擦除

use*_*999 7 c++ vector std

我想知道在C++中从向量中删除元素的最佳实践是什么.

我见过多次使用std :: remove来查找和删除元素,然后使用erase从向量中删除元素.

但是为什么它比使用find获取要删除的元素的迭代器然后使用该迭代器的擦除更好?

谢谢

Man*_*rse 16

std::find然后vector::erase将删除具有给定值的对象的第一次出现vector.

std::vector<int> vec{1,3,3,8,3,5};
vec.erase(std::find(vec.begin(), vec.end(), 3));
//vec == {1,3,8,3,5}
Run Code Online (Sandbox Code Playgroud)

std::remove接下来vector::erase将删除具有给定值的对象的每次出现vector.

std::vector<int> vec{1,3,3,8,3,5};
vec.erase(std::remove(vec.begin(), vec.end(), 3), vec.end());
//vec == {1,8,5}
Run Code Online (Sandbox Code Playgroud)

两者都不是更好,他们只是做不同的事情.

std::remove通常更有用,这就是为什么它更常见; 特别是,当向量中不存在元素时std::remove后跟vector::erase什么都不做,而std::find后面vector::erase有未定义的行为.

注意,"find-erase","remove-erase"都保持元素的相对顺序.如果要从向量中删除元素但不关心元素的结果顺序,可以使用"find-move-pop_back"或"partition-erase":

//find-move-pop_back
std::vector<int> vec{1,3,3,8,3,5};
*std::find(vec.begin(), vec.end(), 3) = std::move(vec.back());
vec.pop_back();

//partition-erase
std::vector<int> vec{1,3,3,8,3,5};
vec.erase(
    std::partition(vec.begin(), vec.end(), [](int v){return v == 3;}),
    vec.end());
Run Code Online (Sandbox Code Playgroud)