LoginSignup
1
0

More than 3 years have passed since last update.

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

Posted at

 はじめに

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 * 型ポインタのように振る舞います。

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修飾子がアスタリスク(*)の右にあるときには、「ポインタそのもの」が不変となると書きました。

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が指し示すデータ」が不変の場合

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

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

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

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

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

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

サンプルコード

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://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

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0