C++ STL 迭代器與 const 結合時有兩種截然不同的語意:迭代器本身不可變,或迭代器指向的元素不可變。混淆兩者是常見錯誤來源。
| 宣告方式 | 對應原生指標 | 可修改迭代器位置 | 可修改元素值 | 典型用途 |
|---|---|---|---|---|
const Container::iteratorContainer::iterator const | T* const (const 指標) | 否 | 是 | 單向遍歷,需修改元素 |
Container::const_iterator | const T* (指向 const 的指標) | 是 | 否 | 只讀遍歷 |
/* effectivecpp.cpp
* Created on: 2013.11.13
* Author: Caroline
* Compiler: eclipse cdt ; gcc 4.7.1
*/
#include <iostream>
#include <vector>
int main() {
std::vector<int> iv = {1, 2, 3, 4, 5};
// 情況 1:const iterator (迭代器本身不可變)
const auto it = iv.begin(); // 等價於 vector<int>::iterator const it
std::cout << "*it = " << *it << std::endl;
*it = 10; // OK:可修改元素值
std::cout << "*it = " << *it << std::endl;
// ++it; // 錯誤:無法修改迭代器位置
iv = {1, 2, 3, 4, 5};
// 情況 2:const_iterator (元素不可變)
auto cit = iv.cbegin(); // C++11 起推薦使用 cbegin()/cend()
// 等價於:std::vector<int>::const_iterator cit = iv.begin();
std::cout << "*cit = " << *cit << std::endl;
++cit; // OK:可移動迭代器
// *cit = 10; // 錯誤:無法修改元素值
std::cout << "*cit = " << *cit << std::endl;
return 0;
}
const iterator (T* const)*it = value;++it, it = other 皆錯誤const_iterator (const T*)const 參考,不可修改元素const 成員函數回傳cbegin(), cend(), crbegin(), crend() 明確取得auto it = c.begin();唯讀遍歷用 auto it = c.cbegin()const Container& 並使用 const_iteratorconst Container::iterator,易誤讀;改用 Container::const_iterator 或 autocbegin()/cend() 而非 begin()/end() 搭配 const 轉換// 錯誤:企圖修改 const_iterator 指向的元素
for (auto it = vec.cbegin(); it != vec.cend(); ++it) {
*it = 0; // 編譯錯誤
}
// 正確:使用非 const 迭代器
for (auto it = vec.begin(); it != vec.end(); ++it) {
*it = 0; // OK
}
// 或使用範圍 for (C++11)
for (auto& elem : vec) {
elem = 0; // OK
}