C++中删除对象的向量

C++中删除对象的向量,c++,vector,visual-studio-2015,erase,C++,Vector,Visual Studio 2015,Erase,我目前正在使用一个向量来保存程序中的人员。我正在尝试用删除它 vectorname.index 我在函数中传递向量,以及要删除的元素。我的主要问题是如何提高代码的编译速度 #include <iostream> #include <string> #include <vector> using namespace std; class person { private: string name; public:

我目前正在使用一个向量来保存程序中的人员。我正在尝试用删除它

vectorname.index

我在函数中传递向量,以及要删除的元素。我的主要问题是如何提高代码的编译速度

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class person {
    private:
        string name;
    public:
        person() {}
        person(string n):name(n){}
        const string GetName() {return name;}
        void SetName(string a) { name = a; }
};

void DeleteFromVector(vector<person>& listOfPeople,person target) {
    for (vector<person>::iterator it = listOfPeople.begin();it != listOfPeople.end();++it) {//Error 2-4
        if (it->GetName() == target.GetName()) {
            listOfPeople.erase(it);
            break;
        }
    }
}

int main(){
    //first group of people
    person player("Player"), assistant("Assistant"), janitor("Janitor"), old_professor("Old Professor");

    //init of vector
    vector<person> listOfPeople = { player, assistant, janitor, old_professor };

    DeleteFromVector(listOfPeople, janitor);
}

无需定义索引,迭代器可用于访问向量中的对象:

for (vector<person>::iterator it = listOfPeople.begin(); it != listOfPeople.end(); ++it) {//Error 2-4
    if (it->GetName() == target.GetName()) {
        listOfPeople.erase(it);
        break;
    }
}

因为下一行是对循环的中断,所以这里不考虑无效的迭代器问题。


无需定义索引,迭代器可用于访问向量中的对象:

for (vector<person>::iterator it = listOfPeople.begin(); it != listOfPeople.end(); ++it) {//Error 2-4
    if (it->GetName() == target.GetName()) {
        listOfPeople.erase(it);
        break;
    }
}

因为下一行是对循环的中断,所以这里不考虑无效的迭代器问题。


从向量中删除对象不需要该循环。只需使用:


从向量中删除对象不需要该循环。只需使用:

此erase remove习惯用法中的remove操作将把除target之外的所有元素移动到向量范围的前面,而erase操作将删除位于末尾且满足target条件的所有元素。这是非常有效的,即使它不像迭代版本那样有表现力



此erase remove习惯用法中的remove操作将把除target之外的所有元素移动到向量范围的前面,而erase操作将删除位于末尾且满足target条件的所有元素。这是非常有效的,即使它没有迭代版本那么有表现力。

为什么在for中定义迭代器,但不使用它?你做的都是错的。您正在使用erase,但没有将其返回值作为新的迭代器,因此在此之后,您将使用无效、损坏的迭代器。还有一种更好的方法,你可以在这里看到,好的,我看到你在使用erase后立即中断,所以我猜你毕竟没有使用无效的迭代器。与其使用所有这些东西,不如使用find_if来找到看门人,并使用它的返回值进行擦除。为什么同时使用它和索引。迭代器的关键是使用它而不是索引。选择一个或另一个,但不能同时选择两者。为什么在for中定义迭代器,但不使用它?这样做完全是错误的。您正在使用erase,但没有将其返回值作为新的迭代器,因此在此之后,您将使用无效、损坏的迭代器。还有一种更好的方法,你可以在这里看到,好的,我看到你在使用erase后立即中断,所以我猜你毕竟没有使用无效的迭代器。与其使用所有这些东西,不如使用find_if来找到看门人,并使用它的返回值进行擦除。为什么同时使用它和索引。迭代器的关键是使用它而不是索引。选择一个或另一个,但不是两个。下一行是中断循环,我们仍然需要考虑无效的迭代器问题吗?啊,这将避免问题。@ MartinZhai感谢信息:下一行是中断循环,我们仍然需要考虑无效的迭代器问题吗?这将避免问题的发生。@MartinZhai感谢您提供的信息:这一个比公认的答案更好-使用std::find_if,而不是自己做这项工作。如果为person类定义了运算符==则可以使用std::find@PaulMcKenzie,返回行中的p对象和目标导致错误。错误活动对象具有与成员函数person::GetName不兼容的类型限定符错误活动对象具有与成员函数person::GetName错误C2662“std::string person::GetNamevoid”不兼容的类型限定符:无法将“this”指针从“const person”转换为“person&@CraftedGaming”删除常量或使GetName成为常量函数。最好将其设置为常量函数。@PaulMcKenzie我将该函数更改为常量,但它仍然包含相同的errors@CraftedGaming-编译时没有错误-这比公认的答案好-使用std::find_if,而不是自己完成工作。如果为person类定义了运算符==则可以使用std::find@PaulMcKenzie,返回行中的p对象和目标导致错误。错误活动对象具有与成员函数person::GetName不兼容的类型限定符错误活动对象具有与成员函数person::GetName错误C2662“std::string person::GetNamevoid”不兼容的类型限定符:无法将“this”指针从“const person”转换为“person&@CraftedGaming”删除常量或使GetName成为常量函数。最好将其设置为常量函数。@PaulMcKenzie我将该函数更改为常量,但它仍然包含相同的errors@CraftedGaming-它编译时没有错误,希望它能解决问题,但请添加对代码的解释,以便用户能够完全理解他/她真正想要的。请参阅。虽然这在技术上可能是正确的,但它并没有解释为什么它解决了问题,或者应该是选择的答案。我们
uld除了帮助解决问题外,还提供教育。谢谢双方。答案现在更新为解释。希望它能解决问题,但请添加代码解释,以便用户能够完全理解他/她真正想要的。请参阅。虽然这在技术上可能是正确的,但它并没有解释为什么它解决了问题,或者应该是选择的答案。除了帮助解决问题,我们还应该进行教育。谢谢你们。答案现在更新为解释。
listOfPeople.erase(
                   remove(listOfPeople(), listOfPeople.end(), target),
                   listOfPeople.end()
                  )