map<int, int> mymap{ {1,10},{2,20} }; //map 容器的鍵為 const 型別,不能被修改 mymap.begin()->first = 100; multimap<int, int> mymultimap{ {10,100},{20,200} }; //multimap 容器的鍵為 const 型別,同樣不能被修改 mymultimap.begin()->first = 100;其中,第 3 行程式碼試圖直接將 mymap 容器中 {1,10} 的鍵改為 100,同樣第 7 行程式碼試圖直接將 mymultimap 容器中 {10,100} 的鍵改為 100,它們都是不能通過編譯的。
class student { public: student(string name, int id, int age) :name(name), id(id), age(age) { } const int& getid() const { return id; } void setname(const string name){ this->name = name; } string getname() const{ return name; } void setage(int age){ this->age = age; } int getage() const{ return age; } private: string name; int id; int age; };在建立 set 容器之前,我們還需要為其設計一個排序規則,這裡假定以每個學生的 id 做升序排序,其排序規則如下:
class cmp { public: bool operator ()(const student &stua, const student &stub) { //按照字串的長度,做升序排序(即儲存的字串從短到長) return stua.getid() < stub.getid(); } };做完以上所有的準備工作後,就可以建立一個可儲存 student 物件的 set 容器了,比如:
set<student, cmp> myset{ {"zhangsan",10,20},{"lisi",20,21},{"wangwu",15,19} };由此建立的 myset 容器中,儲存的資料依次為:
{"zhangsan",10,20}
{"wangwu",15,19}
{"lisi",20,21}
例如,在已建立好的 myset 容器的基礎上,如下程式碼嘗試修改 myset 容器中某個學生的 name 名字:總之,set 和 multiset 容器的元素型別沒有用 const 修飾。所以從語法的角度分析,我們可以直接修改容器中元素的值,但一定不要修改元素的鍵。
set<student>::iterator iter = mymap.begin(); (*iter).setname("xiaoming");注意,如果讀者執行程式碼會發現,它也是無法通過編譯的。
比如,我們只需要借助 const_cast 運算子對上面程式稍作修改,就可以執行成功:有關 const_cast 運算子的用法,由於不是本節重點,這裡不再做詳細講解,有興趣的讀者可自行查閱相關資料。
set<student>::iterator iter = mymap.begin(); const_cast<student&>(*iter).setname("xiaoming");由此,mymap 容器中的 {"zhangsan",10,20} 就變成了 {"xiaoming",10,20}。
再次強調,雖然使用 const_cast 能直接修改 set 或者 multiset 容器中的元素,但一定不要修改元素的鍵!如果要修改,只能採用“先刪除,再新增”的方式。另外,不要試圖以同樣的方式修改 map 或者 multimap 容器中鍵值對的鍵,這違反了 C++ STL 標準的規定。
#include<iostream> #include<set> #include<string> using namespace std; class student { public: student(string name, int id, int age) :name(name), id(id), age(age) { } const int& getid() const { return id; } void setname(const string name){ this->name = name; } string getname() const{ return name; } void setage(int age){ this->age = age; } int getage() const{ return age; } void display()const { cout << id << " " << name << " " << age << endl; } private: string name; int id; int age; }; //自定義 myset 容器的排序規則 class cmp { public: bool operator ()(const student &stua, const student &stub) { //按照字串的長度,做升序排序(即儲存的字串從短到長) return stua.getid() < stub.getid(); } }; int main() { set<student, cmp> mymap{ {"zhangsan",10,20},{"lisi",20,21},{"wangwu",15,19} }; set<student>::iterator iter = mymap.begin(); //直接將 {"zhangsan",10,20} 中的 "zhangsan" 修改為 "xiaoming" const_cast<student&>(*iter).setname("xiaoming"); while (iter != mymap.end()) { (*iter).display(); ++iter; } return 0; }程式執行結果為:
10 xiaoming 20
15 wangwu 19
20 lisi 21