勉強記録　10日目 〜STLの反復子iteratorにおけるconst修飾子〜 - Effective C++ 第3版 -

#　はじめに

Effective C++ 第3版の3項9ページから勉強していきます。
今回は、「STLの反復子iteratorにおけるconst修飾子」についです。

# Effective C++ 第3版 - 3項　可能ならいつでもconstを使おう -

## STLの反復子iteratorにおけるconst修飾子

### STLとは？

STL (Standard Template Library) とは、C++ の標準ライブラリの1つです。

### iteratorとは？

iterator（イテレータ）は日本語では「反復子」と訳される。
配列やarrayクラス、vectorクラスの要素にアクセスする場合などに使われる。
iteratorは、ポインタをモデルにしています。
そのため、iteratorは、 T * 型ポインタのように振る舞います。
下のコードは、int * 型ポインタのように振る舞います。

```cpp
std::vector<int> vec;
std::vector<int>::iterator niter = vec.begin();  // T * 型 ( int * 型)のようなもの
std::cout << "値 : " << *niter << std::endl;
std::cout << "アドレス : " << &(*niter) << std::endl;
```

### const付きiterator

前回の投稿で、
const修飾子がアスタリスク(＊)の左にあるときには、「ポインタが指し示すデータ」が不変、
const修飾子がアスタリスク(＊)の右にあるときには、「ポインタそのもの」が不変となると書きました。

```cpp
int x  = 5;
int x2 = 3;

// const修飾子がアスタリスク(*)の左
const int *p2_x = &x;        // ポインタは非const
                             // データはconst
*p2_x = x2; // コンパイルエラー
 p2_x = &x2;

// const修飾子がアスタリスク(*)の右
int *const p3_x = &x;        //  ポインタはconst
                             // データは非const
*p3_x = x2;
 p3_x  = &x2; // コンパイルエラー
```

では、iteratorの場合はどうなるのでしょうか？

「iteratorが指し示すデータ」が不変の場合

```cpp
std::vector<int>::const_iterator citer = vec.begin();  // ポインタでいう、const T * 型 (const int * 型)
*citer  = 10;  // コンパイルエラー                  　　  // iterator(citer)が指すものの内容は変更不可
++citer;                                               // iterator(citer)が別のものを指し示すことは可能
```

「iteratorそのもの」が不変の場合

```cpp
const std::vector<int>::iterator iter = vec.begin();  // ポインタでいう、T * const 型 ( int * const 型)
*iter = 10;                                           // iterator(iter)が指すものの内容を変更可能
++iter; // コンパイルエラー 　                           // iterator(iter)が別のものを指し示すことは不可
```

「iteratorが指し示すデータ」と「iteratorそのもの」が不変の場合

```cpp
const std::vector<int>::const_iterator cciter = vec.begin();  // ポインタでいう、const T * const型( const int * const型)
*cciter = 10;   // コンパイルエラー                             // iterator(cciter)が指すものの内容は変更不可
 ++cciter;      // コンパイルエラー                             // iterator(cciter)が別のものを指し示すことは不可
```

以下に、勉強で使用したコードを示します。

### サンプルコード

```cpp:3_const_itr.cpp
#include <iostream>
#include <vector>

int main(int argc, char* argv[]) {
  std::cout << "3_const_itr.cpp" << std::endl;
  std::vector<int> vec;
  for (int i = 0; i < 5; i++) {
    vec.push_back(i);
  }

  std::vector<int>::iterator niter = vec.begin();  // T * 型

  const std::vector<int>::iterator iter = vec.begin();  // T * const 型
  *iter                                 = 10;           // iterが指すものの内容を変更可能
  // ++iter; // コンパイルエラー 　// iterが別のものを指し示すことは不可

  std::vector<int>::const_iterator citer = vec.begin();  // const T * 型
  // *citer  = 10; // citerが指すものの内容は変更不可
  ++citer;  // citerが別のものを指し示すことは可能

  const std::vector<int>::const_iterator cciter = vec.begin();
  // *cciter          = 10; // コンパイルエラー
  // ++cciter;              // コンパイルエラー
}
```

### 実行結果

![3_const_itr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367151/0c211a11-000e-3397-56a8-95777cfb3934.png)


## 参考文献

・https://www.amazon.co.jp/gp/product/4621066099/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0
・https://programming.pc-note.net/cpp/iterator.html