vector:
如同一般復合類型一樣,vector 迭代器也可以聲明成:
const vector<int>::iterator it1 = v.begin();
vector<int>::iterator const it2 = v.begin();
但在一般復合類型中 it1 通常是底層 const,ti2是 頂層 const。但在上面兩條聲明語句中 it1, it2 都是頂層 const,即 it1, it2 本身的值不能改變(不能指向其它對象),而其所指對象的值是可以改變的。既然不能通過聲明迭代器 it1 的形式得到底層 const,那么就需要有其它方法來達成咯。這就是 const_iterator。
vector<int>::const_iterator it3 = v.begin();
it3 會是一個底層 const,即其所指對象可以改變,但不能改變其所指對象的值。
1 std::vector<int> v(10, 1); 2 const vector<int>::iterator it1 = v.begin(); 3 // it1++;//改變it1的值是非法的 4 *it1 += 1; 5 cout << *it1 << endl;//輸出2 6 7 vector<int>::iterator const it2 = v.begin(); 8 // it2 = v.end();//改變it2的值是非法的 9 cout << *it2 << endl;//輸出2 10 *it2 += 1; 11 cout << *it2 << endl;//輸出3 12 13 vector<int>::const_iterator it3 = v.begin(); 14 // *it3 += 1;//改變it3所指對象的值是非法的 15 it3++;//讓it3指向v中第一個元素的下一個元素 16 cout << *it3 << endl;//輸出1 17 18 const vector<int>::const_iterator it4 = v.begin(); 19 // it4++;//改變it4的值是非法的 20 // *it4 += 1;//改變it4所指對象的值是非法的 21 22 vector<int>::const_iterator const it5 = v.begin(); 23 // it5++;//改變it5的值是非法的 24 // *it5 += 1;//改變it5所指對象的值是非法的
set:
1 set<int> s; 2 s.insert(1); 3 s.insert(2); 4 set<int>::iterator it = s.begin(); 5 cout << *it << endl;//輸出1 6 // *it += 1;//set里面的元素本身是常量,不可改變
在上面的代碼中,若加上 it += 1,則會報錯:
可以發現 set 的元素是帶有 const 限定符的。
因此要修改 set 里面某個元素的值的話一般需要先刪除需要修改的那個元素,再插入目標值,需要 log(n) 的時間。
當然也可以通過 const_cast 來解除 set 迭代器的底層 const:
1 set<int> s; 2 s.insert(1); 3 s.insert(10); 4 s.insert(100); 5 6 const set<int>::iterator it = s.begin(); 7 int &cnt = const_cast<int&>(*it);//cnt為it所指對象的引用, 但cnt不具有底層const 8 cnt += 100; 9 cout << *it << endl;//輸出101 10 cout << cnt << endl;//輸出101 11 for(auto i : s){ 12 cout << i << " ";//輸出 101 10 100 (set類型對象s的有序性被破壞了) 13 } 14 cout << endl; 15 16 s.insert(1); 17 cout << *s.begin() << endl; 18 for(auto i : s){ 19 cout << i << " ";//輸出 1 101 10 100 20 } 21 cout << endl;
上例中雖然用 const_cast 去掉了迭代器 it 的底層 const,但是卻破壞了 s 的有序性,顯然不是一個好的辦法。因此用 const_cast 改變對象的底層 const 時一定要慎之又慎。
和 vector 迭代器類似的是,const 作用於 set 迭代器也是頂層 const,而 set 又自帶底層 const,所以用 const 限定的 set 迭代器既不能改變所指對象,也不能改變所指對象的值。而 const_iterator 的作用則和 set 迭代器自帶的底層 const 重復了。
1 set<int> s; 2 s.insert(1); 3 s.insert(10); 4 s.insert(100); 5 6 const set<int>::iterator it1 = s.begin(); 7 cout << *it1 << endl;//輸出1 8 // it1++;//非法操作 9 // *it1 += 1;//非法操作 10 11 set<int>::iterator const it2 = s.begin(); 12 cout << *it2 << endl;//輸出1 13 // it2++;//非法操作 14 // *it2 += 1;//非法操作 15 16 set<int>::const_iterator it3 = s.begin(); 17 // *it3 += 1;//非法操作 18 it3++; 19 cout << *it3 << endl;//輸出10
map:
和 set 類似,map 的迭代器也帶有底層 const,不同的是 map 迭代器中只有 key 是 const 的。
1 map<int, int> mp; 2 mp[1] = 2; 3 map<int, int>::iterator it = mp.begin(); 4 cout << (*it).first << " " << (*it).second << endl;//輸出1 2 5 (*it).second += 1; 6 // (*it).first += 1;//有const修飾符,不能改變 7 cout << (*it).first << " " << (*it).second << endl;//輸出1 3
如果加上 (*it).first += 1; 則會報錯:
const 作用於 map 也是頂層 const,而 const_iterator 作用於 map 是底層 const。map 迭代器指向的一個 pair 類型的對象。map 迭代器只有 key(pair 的第一個元素)是 const 的。使用 const_iterator 后則整個 pair 都是 const 的。
1 map<int, int> mp; 2 mp[1] = 2; 3 mp[2] = 3; 4 5 const map<int, int>::iterator it1 = mp.begin(); 6 // it1 = mp.end();//非法操作 7 // it1->first += 1;//非法操作 8 it1->second += 1; 9 cout << it1->first << " " << it1->second << endl;//輸出1 3 10 11 map<int, int>::iterator const it2 = mp.begin(); 12 // it2 = mp.end();//非法操作 13 // it2->first += 1;//非法操作 14 it2->second += 1; 15 cout << it2->first << " " << it2->second << endl;//輸出1 4 16 17 map<int, int>::const_iterator it3 = mp.begin(); 18 it3 = --mp.end();//end是尾后迭代器 19 // it3->first += 1;//非法操作 20 // it3->second += 1;//非法操作,使用const_iterator修飾后it3具有底層const 21 22 const map<int, int>::const_iterator it4 = mp.begin(); 23 // it4 = --mp.end();//非法操作 24 // it4->first += 1;//非法操作 25 // it4->second += 1;//非法操作 26 27 map<int, int>::const_iterator const it5 = mp.begin(); 28 // it5 = --mp.end();//非法操作 29 // it5->first += 1;//非法操作 30 // it5->second += 1;//非法操作
如果試圖給 const_iterator 迭代器改變所指對象的值,則會報錯:
提示 std::pair<const int, int>::second 是只讀的。