【问题标题】:Using erase for removing an element in an array of class objects使用擦除删除类对象数组中的元素
【发布时间】:2021-01-11 18:20:52
【问题描述】:

我想删除给定卷号的特定学生对象。从学生列表中使用 STL 中的擦除操作。以下是我的班级设计。 但是编译器在我使用擦除功能的地方显示以下错误消息。

没有重载函数“std::vector<_tp _alloc>::erase [with _Tp=Student, _Alloc=std::allocator]”的实例与参数列表匹配——参数类型为:(Student ) -- 对象类型为:std::vector>

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

class Student
{
    int roll;
    char *name;
    int score;

    public:
        Student(int r=0)
        {
            roll=r;
        }

        void get_data()
        {
            cout<<"Enter roll : ";
            cin>>roll;
            cout<<"Enter name : ";
            cin>>name;
            cout<<"Score : ";
            cin>>score;
        }

        void show_data()
        {
            cout<<"Roll : "<<roll<<endl;
            cout<<"Name : "<<name<<endl;
            cout<<"Score : "<<score<<endl;
        }

        int ret_score()
        {
            return score;
        }

        int ret_roll()
        {
            return roll;
        }
};

class Student_array
{
    public:
    vector <Student> Student_array;
    vector <Student>::iterator it;

    void add_student()
    {
        Student s;
        s.get_data();
        Student_array.push_back(s);
    }

    void remove_student()
    {
        int roll;
        cout<<"Enter roll no. of the student to be removed : ";
        cin>>roll;
        for(int i=0;i<Student_array.size();i++)
        {
            if(roll==Student_array[i].ret_roll())
            {
                Student_array.erase(Student_array[i]);
                break;
            }
        }
        cout<<"Roll no. not found enter a valid roll no.\n";
    }
};

【问题讨论】:

  • 旁注:存储迭代器 (vector &lt;Student&gt;::iterator it;) 存在一定风险,因为它很容易通过在 vector 中添加或删除项目而变得无效。请参阅Iterator invalidation rules,了解标准修订版的逐个标准修订细分,了解您可以和不可以逃避的事情。

标签: c++ oop stl


【解决方案1】:

std::vector::erase() 将迭代器作为输入,而不是 Student 对象,例如:

void remove_student()
{
    int roll;
    cout << "Enter roll no. of the student to be removed : ";
    cin >> roll;
    for(int i = 0; i < Student_array.size(); ++i)
    {
        if (roll == Student_array[i].ret_roll())
        {
            Student_array.erase(Student_array.begin() + i);
            return; // <-- not 'break'!
        }
    }
    cout << "Roll no. not found enter a valid roll no.\n";
}

或者,您可以使用std::find_if() 来查找所需的Student,而不是使用手动循环,例如:

void remove_student()
{
    int roll;
    cout << "Enter roll no. of the student to be removed : ";
    cin >> roll;
    auto iter = std::find_if(Student_array.begin(), Student_array.end(),
        [=](Student &s){ return s.ret_roll() == roll; }
    );
    if (iter != Student_array.end())
        Student_array.erase(iter);
    else
        cout << "Roll no. not found enter a valid roll no.\n";
}

【讨论】:

  • 感谢您的回答。只是一个小查询,如果假设我想按分数的降序对学生进行排序和显示,那么我应该如何构建函数?我可以使用范围从 rbegin() 到 rend() 的排序模板,但我不明白如何将排序与学生分数联系起来
  • 使用比较score 值的自定义谓词,例如:std::sort(Student_array.begin(), Student_array.end(), [](Student &amp;s1, Student &amp;s2){ return s1.ret_score() &gt; s2.ret_score(); }); 或者,如果您为Student 实现operator&gt;,在score 上进行比较,那么您可以使用std::greater对于谓词,例如:class Student { ... bool operator&gt;(const Student &amp;rhs) const { return score &gt; rhs.score; } }; std::sort(Student_array.begin(), Student_array.end(), std::greater&lt;Student&gt;());
  • 非常感谢,真的很有帮助
【解决方案2】:

你必须使用迭代器来擦除一个元素

for (auto iter = Student_array.begin(); iter != Student_array.end(); ++iter)
{
    if (roll != iter->ret_roll())
        continue;

    Student_array.erase(iter);
    break;
}

【讨论】:

    猜你喜欢
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    • 2017-03-21
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多