set的迭代器it有const修饰符,那么对它元素的修改就必然不能成功了。但是有时候遇到要修改stl set元素的问题,这个问题一般的解决方法是先erase这个元素,然后再insert,这样效率很低,所以得找更有效的方法,开始的时候编译始终通不过。如果利用const_cast(*it)把it映射成一个引用的对象,那么就可以对它进行修改了。更加通用的方法如下:
#include <set> #include <string> #include <iostream> using namespace std; class CEmployee { public: CEmployee(); ~CEmployee(); const string getName() const; void setName(const string name); const string getTitle() const; void setTitle(string title); int getID() const; void setID(int id); private: int m_id; string m_username; string m_title; }; CEmployee::CEmployee() { } CEmployee::~CEmployee() { } const string CEmployee::getName() const { return m_username; } void CEmployee::setName(const string username) { m_username = username; } const string CEmployee::getTitle() const { return m_title; } void CEmployee::setTitle(string title) { m_title = title; } int CEmployee::getID() const { return m_id; } void CEmployee::setID(int id) { m_id = id; } class sortByID { public: bool operator() (CEmployee const &_A, CEmployee const &_B) const { if(_A.getID() < _B.getID()) return true; if(_A.getID() == _B.getID()) return _A.getName().compare(_B.getName()) < 0; return false; } }; int main() { set<CEmployee, sortByID> empIDSet; // se是雇员的set, set<CEmployee, sortByID> ::iterator iter; CEmployee employeeInfo; employeeInfo.setName("employee_one"); employeeInfo.setTitle("employee"); employeeInfo.setID(1); empIDSet.insert(employeeInfo); CEmployee employeeInfo2; employeeInfo2.setName("employee_two"); employeeInfo2.setTitle("CFO"); employeeInfo2.setID(5); empIDSet.insert(employeeInfo2); CEmployee employeeInfo3; employeeInfo3.setName("employee_three"); employeeInfo3.setTitle("manager"); employeeInfo3.setID(3); empIDSet.insert(employeeInfo3); // 第一步:找到要改变的元素 iter = empIDSet.find(employeeInfo2); if(iter!=empIDSet.end()) { // 第二步:拷贝这个元素 CEmployee e(*iter); // 第三步:删除这个元素; empIDSet.erase(iter++); // 自增这个迭代器以保持它有效(参见条款9) // 第四步:修改这个副本 e.setTitle("Corporate Deity"); // 第五步:插入新值;提示它的位置 empIDSet.insert(iter, e); // 和原先元素的一样 //不起效果 //static_cast<CEmployee>(*iter).setTitle("Corporate Deity"); } else { cout<<" Failed/n"<<endl; } for (iter=empIDSet.begin(); iter!=empIDSet.end(); iter++) { cout<<iter->getID()<<" " <<iter->getName()<<" " <<iter->getTitle()<<endl; } return 0; }
参考:
effective STL 条款22:避免原地修改set和multiset的键