boostメモ (foreach)

boost/foreach.hppはイテレータを用いたコンテナの順次参照をより直感的に記述できるようにするもの。
http://www.kmonos.net/alang/boost/classes/foreach.html

Javaとかである

for(Hoge hoge : HogeList) {}

のような記法を可能にする。C++0xだとfor文の記法としてJavaの方法が機能拡張されてるみたい。
http://d.hatena.ne.jp/faith_and_brave/20070920/1190285157

なお、BOOST_FOREACHは下記のようにマクロとして定義されているので、中に入れるコード上の文字列が影響するみたい。
コンテナの要素の記述にテンプレートの"<>"がでてくるような場合は予めtypedefしないとだめ。

#define BOOST_FOREACH(VAR, COL)                                                                                   \
    BOOST_FOREACH_PREAMBLE()                                                                                      \
    if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else   \
    if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_BEGIN(COL)) {} else     \
    if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_end) = BOOST_FOREACH_END(COL)) {} else       \
    for (bool BOOST_FOREACH_ID(_foreach_continue) = true;                                                         \
              BOOST_FOREACH_ID(_foreach_continue) && !BOOST_FOREACH_DONE(COL);                                    \
              BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_NEXT(COL) : (void)0)                            \
        if  (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else                      \
        for (VAR = BOOST_FOREACH_DEREF(COL); !BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true)

以下、サンプル。

/* -*- coding:utf-8 -*- */
/**
 * foreach.hpp
 */

#include <iostream>
#include <string>
#include <vector>
#include <map>

#include <boost/foreach.hpp>

int main() {
    std::vector<std::string> strVec;

    strVec.push_back("one");
    strVec.push_back("two");
    strVec.push_back("three");

    std::cout << "--- strVec ---" << std::endl;
    BOOST_FOREACH ( const std::string& str, strVec) {
        std::cout << str << std::endl;
    }
    std::cout << std::endl;

    std::map<int, std::string> intStrMap;

    intStrMap[1] = "one";
    intStrMap[2] = "two";
    intStrMap[3] ="three";

    std::cout << "--- intStrMap ---" << std::endl;
    //
    // この書き方ではエラーになる
    // BOOST_FOREACH ( const std::map<int, std::string>::value_type& intStr, intStrMap) {
    //     std::cout << intStr.first << " => " << intStr.second << std::endl;
    // }
    //
    // <>を含むような場合はtypedefする
    typedef std::map<int, std::string> IntStrMap;
    BOOST_FOREACH ( const IntStrMap::value_type& intStr, intStrMap) {
        std::cout << intStr.first << " => " << intStr.second << std::endl;
    }

    return 0;
}

$ g++ foreach.cpp
$ ./a.out
--- strVec ---
one
two
three

--- intStrMap ---
1 => one
2 => two
3 => three