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 01:00:00
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-2019 project-enigma.
Generated by CL-PREFAB.