はじまり、はじまり

今日はお勉強会ではじめてC++の5行以上あるようなプログラムを書いた。JavaとかRubyとかはそこそこ書けるので、一気に覚えればすぐに書けるようになりそうな予感。

今日の結果を忘れないうちに、とりあえずなにかやってみようと思って、なにかいいテーマはないかなと考えてたけど、あんまいいのが思いつかない。apt-cache search boostとか見ているうちにregexでもやってみようと思い立ち、いろいろがんばる。

準備

でびあんでapt-getする。

  • libboost-regex1.33.1
    • これだけでは so が入っただけ
  • libboost-regex-dev
    • regex.hppとかが入ったけれどboost本体がない
  • libboost-dev
    • これでようやくすべてそろったっぽい

コードを書いてみる

まずは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_resultsregex_searchに渡せるらしいので、せっかくだからiteratorで順に表示するようにしたい。

で、ひたすら苦労していたのが for 文の中身。

for (string::const_iterator i = results.begin(); i != results.end(); i++) {
    cout << *i << endl;
}

って書いてたのね。エラーが出るんだけど、ごちゃごちゃしていてとても読む気がしない。でもがんばって''の対応を見ながら読んでいくと、どうやら != で型が違うよ、と怒られているらしい。

ようするに results.begin() が返す型が string::const_iterator じゃないってのは分かるんだけれど、じゃあ何を書けばいいんだよ、と悩む。Javaの感覚なら smatch は MatchResults> なんだから Iterator を返してくれよ、と思ったけれど、どうもちがうらしい。

正解は

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も読んでみたいです。