2015-09-19-01-STL書籍の掲載コードをCL-STLで書いてみよう
>> Site top >> weblog >> 月別アーカイブ >> 2015年09月のlog >> 2015-09-19-01-STL書籍の掲載コードをCL-STLで書いてみよう
最終更新日付:2015/09/19 01:00:00
STL書籍の掲載コードをCL-STLで書いてみよう
2015 年 09 月 19 日
Scott Meyers の「Effective STL」、第47項の「書き込み専用コードの作成は避けよう」に出てくる、以下のコード例を CL-STL でやってみた、という話。
お題は以下の通りだった。
- vector の中で値が x より小さい全ての要素を削除するとしよう。ただし、y 以上の値が最後に出現する位置より前にある要素は保持する。
で、Effective STL に掲載されていた C++ コードは以下のようなものだったワケだ。ちなみに趣旨は、「後で読む時に困るようなコードは書くのヤメとけ」という話。
vector<int> v; int x, y; ... v.erase( remove_if( find_if( v.rbegin(), v.rend(), bind2nd( greater_equal<int>(), y ) ).base(), v.end(), bind2nd( less<int>(), x ) ) v.end() );
さて、これが Common Lisp + CL-STL ではどうなるかというと、こうなる。ちなみに、v / x / y には値を設定して実際に動かし、さらに結果も表示させている。
* (let ((v (new stl:vector #{5 1 8 2 9 7 3 0 6 4})) (x 5) (y 7)) (stl:erase v (stl:remove-if (stl:base (stl:find-if (stl:rbegin v) (stl:rend v) (stl:bind2nd #'>= y))) (stl:end v) (stl:bind2nd #'< x)) (stl:end v)) (stl:shrink-to-fit v) (stl:data v)) ;=> WARNING: bind2nd is deprecated. ; WARNING: bind2nd is deprecated. ; ; #(5 1 8 2 9 7 6)
‥‥‥おっと、0x11 以降では bind2nd は deprecated だった。では以下のように変えてみよう。これで警告は出ないはず。
* (let ((v (new stl:vector #{5 1 8 2 9 7 3 0 6 4})) (x 5) (y 7)) (stl:erase v (stl:remove-if (stl:base (stl:find-if (stl:rbegin v) (stl:rend v) (stl:bind #'>= :1 y))) (stl:end v) (stl:bind #'< :1 x)) (stl:end v)) (stl:shrink-to-fit v) (stl:data v)) ;=> #(5 1 8 2 9 7 6)
正直、「stl: って何回書かせるねん!」と言いたくなるな。しかし CL パッケージのシンボルとぶつかりまくりなので仕方がない。ひとまずはコードが期待通りに動作しているみたいなので良しとしよう。それより気になるのは、CL-PREFAB のキーワードハイライトが正しく動作していないことだ。(少なくともこれを書いている時点では)remove-if や find-if の if 部分だけ青色になってる。やれやれ。どうやって直すんだっけ。
‥‥‥まぁ、そんな感じで、今後は面白そうな STL コードをちょっとずつ CL-STL コードにしてみようかと思っている。CL-STL の紹介になる気もするし、いいんではなかろうか。
コメント
このページのタグ
Page tag : STLとその移植
Page tag : Common Lisp
Copyright(C) 2005-2021 project-enigma.
Generated by CL-PREFAB.