2015-10-09-01-STL書籍の掲載コードをCL-STLで書いてみよう-7 - project-enigma

2015-10-09-01-STL書籍の掲載コードをCL-STLで書いてみよう-7

>> Site top >> weblog >> 月別アーカイブ >> 2015年10月のlog >> 2015-10-09-01-STL書籍の掲載コードをCL-STLで書いてみよう-7

最終更新日付:2015/10/09 20:41:23


STL書籍の掲載コードをCL-STLで書いてみよう-7

2015 年 10 月 09 日

連想コンテナの再実装を裏でやりつつ、引き続き「Effective STL」のコードを CL-STL で書いていこう。今回は、第27項、『コンテナのconst_iteratorをiteratorに変換するには、distanceとadvanceを使おう』が対象。今回のもコードは少なめ。

書籍のコードは以下のようなモノだった。ポイントは、const_iterator から iterator を作成することはできないということ。だからコンテナ本体から beginiterator を作成し、そこから手持ちの const_iterator の距離分 advance させることで必要なモノを手に入れましょう、という話だ。

typedef deque<int> IntDeque;
typedef IntDeque::iterator Iter;
typedef IntDeque::const_iterator ConstIter;
IntDeque d;
ConstIter ci;
...
Iter i( d.begin() );
advancd( i, distance<ConstIter>( i, ci ) );

 

これはタイプシステムを構成する要素のひとつと言っていい。元のコンテナから非 const な反復子を取得することができない状況において、const 反復子から非 const 反復子を取得できてしまうなら、その const-ness にはなんの意味もないということになってしまう。その点で言えば当然キャストもダメだし、reinterpret_cast なんかしたら未定義の世界に飛び込む。

もちろん CL-STL も同じ考え方に基づいているから、それをやりたければ同じようにすることになる。オブジェクトに対する const-ness という考え方がないので、const-iterator を取得するには cbegin / cend を使うことになる。

(let* ((d (new stl:deque #{0 1 2 3 4 5 6 7 8 9}))
       (ci (stl:find (stl:cbegin d) (stl:cend d) 5)))
  (let ((i (stl:begin d)))
    (stl:advance i (stl:distance i ci))
    i))

 

‥‥‥まぁこんな話だ。そしてあっさり C++ の話に戻るけれど、非 const なコンテナさえあれば「非 const 反復子を手に入れる資格」があるものとみなされるわけだよな。でも、advancedistance が必要になるのはやっぱり非効率だ。これはランダムアクセス反復子であれば非効率というほどのものではないけれども、双方向反復子以下の場合は無視できないコストだ。つまり、listforward_list、および全ての連想コンテナだ。あまり頻繁には使わないかもしれないけれど、const_iterator から同じ位置を指す iterator を生成するような非 const のメンバ関数がコンテナにあればいいのにな、と思う。

 

コメント

このページにコメントする

 

このページのタグ

Page tag : STLとその移植

Page tag : Common Lisp

 

 


Copyright(C) 2005-2017 project-enigma.
Generated by CL-PREFAB.