今日はお勉強会ではじめてC++の5行以上あるようなプログラムを書いた。JavaとかRubyとかはそこそこ書けるので、一気に覚えればすぐに書けるようになりそうな予感。
今日の結果を忘れないうちに、とりあえずなにかやってみようと思って、なにかいいテーマはないかなと考えてたけど、あんまいいのが思いつかない。apt-cache search boostとか見ているうちにregexでもやってみようと思い立ち、いろいろがんばる。
準備
でびあんでapt-getする。
コードを書いてみる
まずはregexオブジェクトみたいなのをどうやって作るか?
Regex re = new Regex("/hoge/");
ってやりたくなるところ。http://www.boost.org/libs/regex/doc/regex_match.htmlの下のほうにあるサンプルを見ると、
regex expression("([0-9]+)(\\-| |$)(.*)");
って書いてある。newは使うなって言ってたから、こうやって書くのがいいのかな。
で、まずregexってなによ、と思った。さっきのサイトをいろいろ見ているうちに、typedefを発見し、別名がつけられるっぽいことが分かった。見ているうちにstringってのもbasic_string<ほげほげ>だったらしいことも発覚。
次。
()が複数あったとき、(phpの$matchesみたいな)match_results
で、ひたすら苦労していたのが for 文の中身。
for (string::const_iterator i = results.begin(); i != results.end(); i++) { cout << *i << endl; }
って書いてたのね。エラーが出るんだけど、ごちゃごちゃしていてとても読む気がしない。でもがんばって''の対応を見ながら読んでいくと、どうやら != で型が違うよ、と怒られているらしい。
ようするに results.begin() が返す型が string::const_iterator じゃないってのは分かるんだけれど、じゃあ何を書けばいいんだよ、と悩む。Javaの感覚なら smatch は MatchResults
正解は
for (smatch::iterator i = results.begin(); i != results.end(); i++) { cout << *i << endl; }
でした。
Javaだと
Iterator<Result<String>> i = resultset.iterator();
だけど、C++はiteratorのニュアンスと、「文字列のイテレータ」を「文字列>イテレータ」と書くのか「イテレータ>文字列」と書くのかの違いがあるように思った。
コンパイル
ここまでもちまちまコンパイルしながら確認していたけれど、イテレータの問題が解決した瞬間に、いままでとは激しく傾向の違うエラーが出るようになった。というより、それで初めてイテレータのほうはうまくいったっぽいと分かった。
で、よくよく眺めてみると、最後にひっそりと
collect2: ld returned 1 exis status
と書いてあるので、そういや .so あるんだったよな、と思い、ググって見ると -lboost_regexをつければよいとこのこと。そういえば命名規則みたいなので分かるんだった。
まとめ
ということで、ようやくコンパイルも通り、ちゃんと動くようになりました。
書き終わってみると、まあこうなるよな、というきれいなかんじにまとまることができました。
次はgetopt, gettextとかやってみたいね。あとcTemplateも読んでみたいです。