STL容器中的Const函数

时间:2011-12-09 23:54:31

标签: c++ stl const

我在使用c ++

中的STL容器时遇到问题

功能1;

void addStudent(const Student &s){                       
    set<GradeColumn>::iterator itr;

    for(itr = gradeColumns.begin(); itr != gradeColumns.end(); itr++){
        itr->addStudent(s, DID_NOT_COMPLETE);
    }
}

功能2:

void addStudent(const Student &s,  int grade) const {
    column.insert(pair<Student, int>(s, grade));
}

好的,所以在函数1中我使用addStudent,但编译器给出了一个错误,除非我将addStudent声明为const函数(错误是“对象具有与成员函数不兼容的类型限定符”)。 / p>

但是如果我确实将addStudent声明为const函数,那么column.insert(...)会给我下一个错误:“没有重载函数的实例匹配参数列表和对象9该对象具有阻止匹配的类型限定符)”。

有没有办法解决这个问题?我错过了什么吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

std::set的键始终不变。这是容器的要求,因为元素按键值排序,如果键是可变的,则容器无法保证其不变量得到维护。

如果GradeColumn上的关系运算符与您在insert()成员函数中需要访问的内容无关,那么您可以声明这些成员对象mutable,以便您可以修改它们即使关键对象本身是不变的。

答案 1 :(得分:1)

这里的问题是您尝试修改的类也是集合中的。这需要不可变。即,一旦项目在集合中,更改密钥是不正确的行为。

您需要考虑不同的结构,我建议您将密钥元素提取到单独的密钥结构中,并使用映射将密钥映射到结构的可变数据内容。

答案 2 :(得分:1)

答案取决于你对我评论的回答。如果你的答案是:

是的,addStudent可以更改GradeColumn订单

答案是:关联容器设计为您提供了,如其他答案所述。

不,addStudent无法更改GradeColumn订单

答案是:关联容器再次设计罢工。

修复是(草图):

class GradeColumnElement {
    mutable GradeColumn col;

    friend bool operator<(const GradeColumnElement& left, const GradeColumnElement& right) {
        return left.col < right.col;
    }

public:
    GradeColumnElement (const GradeColumn& col) : col(col) {
    }

    // const interface: 
    // modifications of GradeColumn that do NOT affect ordering
    void addStudent(const Student &s, int grade) const {
        col.addStudent (s, grade);
    }
};

然后您使用set<GradeColumnElement>代替set<GradeColumn>