我在使用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该对象具有阻止匹配的类型限定符)”。
有没有办法解决这个问题?我错过了什么吗?
谢谢!
答案 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>
。