gcc の typeof 拡張で型推論な foreach をエレガントに実現する

C++ の for_each は、無名関数が書けないおかげで全く使い物にならないわけですが、それでも foreach を書かないと発狂しそうになるときはマクロでどうにかごまかしてきました。

#define FOREACH(t, it, col) \
  for (t::const_iterator it = col.begin(); it != col.end(); ++it)

わかる人にはわかるので、まぁこれでもいいかなと思っていたら思わぬ落とし穴が・・・。

FOREACH (std::map, it, m) {
  ...
}

としたら、引数が4つあるよといわれた! ショック。

これを解決すべく奔走したところ、本当はマクロに可変長引数渡す方法を探していたのに、もっとエレガントな方法を発見。それが、gcc の typeof 拡張で、typeof(var) と書くと var の静的な型に置き換えてくれるようだ。

#define FOREACH (it, col) \
  for (typeof(col.begin()) it = col.begin(); it != col.end(); ++it)

すばらしい!

FOREACH (it, m) {
  ...
}

現実的には本当にかっこいい型推論とかしてくれなくても、この程度でも十分現状より楽になる。すばらしいというのも変な話だ。typeof 拡張は他にも応用できそうだ。当然こんなこともできる。

#define VAR(var, val) \
  typeof(val) var = val

VAR(x, 10);
std::cout << x << std::endl;