首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ const 與迭代器完整指南:const_iterator 與 iterator 的區別

     編輯:關於C++

前言

C++ STL 迭代器與 const 結合時有兩種截然不同的語意:迭代器本身不可變,或迭代器指向的元素不可變。混淆兩者是常見錯誤來源。

一、兩種 const 的語意對照

宣告方式對應原生指標可修改迭代器位置可修改元素值典型用途
const Container::iterator
Container::iterator const
T* const (const 指標)否是單向遍歷,需修改元素
Container::const_iteratorconst 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 成員函數回傳
  • C++11 提供 cbegin(), cend(), crbegin(), crend() 明確取得

四、最佳實務

  1. 預設使用 auto it = c.begin();唯讀遍歷用 auto it = c.cbegin()
  2. 函數參數若不修改容器,應接受 const Container& 並使用 const_iterator
  3. 避免直接寫 const Container::iterator,易誤讀;改用 Container::const_iterator 或 auto
  4. C++11 起優先使用 cbegin()/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
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved