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

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

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

最終更新日付:2015/10/01 07:43:35


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

2015 年 10 月 01 日

10月になっちゃったなぁ。引き続き、「Effective STL」のコードを CL-STL で書いてみよう。今回は、第17項、『余分な容量を取り除くには「swap技法」を使おう』が対象。今回のもコードは少なめ、だがまたバグを踏んだ。

書籍のコードは以下のようなモノだった。スタック上に一時オブジェクトとしてコピーを作成し、それをコピー元と swap することで余分な容量を削減するのだな。

vector<Constestant>( contestants ).swap( contestants );

 

実際問題としては、もはや「swap技法」というのは古い。C++03 以降、標準には shrink_to_fit があるからだ。これなら一時オブジェクトさえ必要ない。以下のように書くだけだ。

contestants.shrink_to_fit();

 

もちろん CL-STL も stl:shrink-to-fit を備えている。これを使えば、以下のように書ける。いつも通り、ちゃんと動くようにしている。

(let ((v (new stl:vector 100 0)))
  (stl:assign v #{1 2 3})
  (stl:shrink-to-fit v)
  (stl:data v))

;=> #(1 2 3)

 

とはいえ、 stl:shrink-to-fit*features*:cl-stl-0x98 がある状態で読み込んだ CL-STL では使えない。それに、書籍にあるコードがどう書かれるのかを示すのがこのシリーズ(?)の趣旨なので、ちゃんと対応する「swap技法」を示しておこう‥‥‥と思って以下のようにしたらエラーになった。およよ。

* (let ((v (new stl:vector 100 0)))
   (stl:assign v #{1 2 3})
   (stl:swap v (new stl:vector v))
   (stl:data v))

; in: LET ((V (NEW CL-STL:VECTOR 100 0)))
;     (CL-STL:SWAP V (NEW CL-STL:VECTOR V))
; --> LET* MULTIPLE-VALUE-BIND MULTIPLE-VALUE-CALL FUNCTION FUNCALL 
; ==>
;   (SB-C::%FUNCALL #'(SETF CL-STL::__NEW-VECTOR) #:NEW8 #:V7)
; 
; caught STYLE-WARNING:
;   undefined function: (SETF CL-STL::__NEW-VECTOR)
; 
; compilation unit finished
;   Undefined function:
;     (SETF CL-STL::__NEW-VECTOR)
;   caught 1 STYLE-WARNING condition

 

あー‥‥‥なるほど。現在の stl:swap の実装では、「setf 可能な場所」でなければ指定できないんだな。これはバグっぽいな。それでは、ひとまず以下のようにしておこう。

* (let ((v (new stl:vector 100 0)))
   (stl:assign v #{1 2 3})
   (let ((tmp (new stl:vector v)))
     (stl:swap v tmp))
   (stl:data v))

;=> #(1 2 3 NIL NIL NIL NIL NIL)

 

さて、上記の結果と、先にやった stl:shrink-to-fit を使った例では、明らかに結果に違いがあるのがわかるだろう。「swap技法」については、Effective STL にも書かれている通りで、要素数ジャストまで容量が切り詰められるとは限らない。上記の結果でもそうなっているし、どうやら CL-STL の stl:vector の最小容量は 8 のようだ。

さて、バグの話だけれど‥‥‥次回にしようかな。

 

コメント

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

 

このページのタグ

Page tag : STLとその移植

Page tag : Common Lisp

 

 


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