如何正确使用'mutable',这样集合迭代器就不会是常量?



我试图删除代码中的员工,并将他的工资改回0,但我在函数中得到的只是他的id。我使用了该集合的内置迭代器,但发现它是const。我如何使用可变或其他方式将他的工资更改为0?我有一名员工和一名经理——经理可以雇佣或解雇该员工,这将改变他的工资(显然(。这是我的代码:

class Manager : public Citizen {
protected:
int salary;
std::set<Employee> employees;
void removeEmployee(const int id) {
mutable std::set<Employee>::iterator employee;
for (employee = this->employees.begin(); employee != this->employees.end(); employee++) {
if (employee->getId() == id) {
employee->setSalary(0);
this->employees.erase(employee);
return;
}
}
throw EmployeeNotHired();
}

我得到的错误-

C:UsersUserCLionProjectshw2CppManager.h:53:50: error: non-member 'employee' cannot be declared 'mutable'
mutable std::set<Employee>::iterator employee;
^~~~~~~~
C:UsersUserCLionProjectshw2CppManager.h:57:42: error: passing 'const mtm::Employee' as 'this' argument discards qualifiers [-fpermissive]
employee->setSalary(0);

我该怎么办?

****编辑****我试着把它改成:

class Employee : public Citizen {
protected:
mutable int salary;
mutable int score;
std::set<Skill> skills;

但我仍然无法将工资更改为0。

error: passing 'const mtm::Employee' as 'this' argument discards qualifiers [-fpermissive]
employee->setSalary(0);

这不是它的工作方式。如果成员标记为可变(mutable int salary;(而不是迭代器,则可以通过const引用更改值。

但是,为什么要在删除薪资之前将其设置为零?无论如何,如果更改集合中的值会影响该集合的顺序,则是不允许的,因此通常这是个坏主意。

std::set的设计确保了集合的元素"不能被修改";即它们只能通过常量引用来访问。这是有充分理由的:std::set依赖于其元素在整个生命周期内保持不变的顺序来维护其内部搜索树数据结构。

处理此问题的方法有:

  1. setSalary声明为常量成员函数。(这不是一个好主意,因为设置salary可能会以const函数所不期望的方式修改对象。(
  2. 提取员工(C++17(
    //employee->setSalary(0);
    //this->employees.erase(employee);
    auto node = employees.extract(employee);
    node.value().setSalary(0);
    
  3. 选择不同的数据结构,例如从id到Employeestd::vector<Employee>std::unordered_map<int, Employee>映射

但是,除非setSalary函数具有除修改Employee对象之外的效果,否则只需从集合中删除该对象;无论如何,该对象都会在此过程中删除。。。

最新更新