2017-03-27 10 views
0

現在、プログラム内の人を保持するためのベクトルを使用しています。私は関数内のベクトルと同様に、私は削除したい要素を渡すC++ベクトル内のオブジェクトを削除する

vectorname.erase(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); 
} 
+1

あなたは 'for'でイテレータを定義していますが、使用していませんか? –

+0

これはすべて間違っています。あなたは 'erase'を使っていますが、戻り値を新しいイテレータとして取っていないので、無効で壊れたイテレータを使用しています。そして、これを行うもっと良い方法があります。http://en.cppreference.com/w/cpp/algorithm/removeとhttps://en.wikipedia.org/wiki/Erase%E2%80でご覧になれます。 %93remove_idiom –

+0

OK、私は 'erase'を使った直後にあなたの' break'を見るので、あなたは無効なイテレータを使っていないと思います。 –

答えて

2

indexを定義する必要がイテレータは、ベクター内のオブジェクトにアクセスするために使用することができ、ありません:

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

次の行は、forループを分割することですので、私たちは、無効なイテレータを考慮していませんここの問題。

+1

次の行はforループを壊すことですが、まだ無効な反復子の問題を考慮する必要がありますか? –

+0

ああ、それは問題を避けるでしょう。 –

+0

@MartinZhai情報あり​​がとうございました:) – CraftedGaming

1

ベクターからオブジェクトを削除するためにループを実行する必要はありません。ちょうどstd::find_if

#include <algorithm> 
//... 
void DeleteFromVector(vector<person>& listOfPeople, const person& target) 
{ 
    // find the element 
    auto iter = std::find_if(listOfPeople.begin(), listOfPeople.end(), 
          [&](const person& p){return p.GetName() == target.GetName();}); 

    // if found, erase it 
    if (iter != listOfPeople.end()) 
     listOfPeople.erase(iter); 
} 
+0

これは受け入れられた答えよりも優れています。自分で作業するのではなく、std :: find_ifを使用してください。そしてpersonクラスのoperator ==が定義されていれば、std :: find() – Tim

+0

@PaulMcKenzieを使うことができます。返り値の "p"オブジェクトと "target"はエラーを引き起こしています。 メンバ関数 "person :: GetName"と互換性のない型修飾子を持つオブジェクトがエラー(アクティブ) メンバ関数 "person :: GetName"と互換性のない型修飾子を持つオブジェクトがエラー(アクティブ) エラーC2662 'std :: string person :: GetName(void)': 'this'ポインタを 'const person'から 'person'に変換することはできません – CraftedGaming

+0

@CraftedGaming次に、 'const'を削除するか、' GetName const関数。それを 'const'関数にする方が良いでしょう。 – PaulMcKenzie

関連する問題