BOOST_FOREACHの使い方
C++のコンテナ類を列挙するときに便利なのがboost::foreach。可変長配列であるvectorを列挙する場合は以下の感じ。
//--------------------------------------------------------------------------- #include <iostream> #include <string> #include <vector> #include <boost/foreach.hpp> #include <tchar.h> //--------------------------------------------------------------------------- class CPlayer { public: CPlayer(const std::string& name, const std::string& position, int number) : Name(name), Position(position), Number(number) { } std::string Name; std::string Position; int Number; }; int _tmain(int argc, _TCHAR* argv[]) { std::vector<CPlayer> Players; Players.push_back(CPlayer("Kazuyoshi MIURA", "FW", 11)); Players.push_back(CPlayer("Shoji JO", "FW", 9)); Players.push_back(CPlayer("Motohiro YAMAGUCHI", "MF", 6)); // コンテナを列挙する BOOST_FOREACH(const CPlayer& Player, Players) { std::cout << Player.Name << ',' << Player.Position << ',' << Player.Number << std::endl; } }
BOOST_FOREACHの第1引数にコンテナの要素型、第2引数にコンテナを渡すだけで列挙してくれるので、forループの為にイテレータを宣言したり*1、std::for_eachの為に関数オブジェクトを定義する*2必要が無い。
STLの連想配列であるstd::mapをBOOST_FOREACHで列挙する場合、列挙型に値の型を指定しがち。この場合はエラーとなる。
typedef std::map<UnicodeString, TIniFile*> CConfigTable; CConfigTable ConfigTable; BOOST_FOREACH(TIniFile* pInifile, ConfigTable) { // ←コンパイルエラー TDateTime LastUpdate = pInifile->ReadTime("GLOBAL", "LastUpdate", TDateTime()); }
std::mapをBOOST_FOREACHで列挙する場合に使用する要素型は、std::mapで定義されているtypedef名*3のうち、value_typeが要素型となる。
これはstd::pair型なので、firstがキー、secondが値に対応する。
typedef std::map<UnicodeString, TIniFile*> CConfigTable; CConfigTable ConfigTable; BOOST_FOREACH(CConfigTable::value_type Elem, ConfigTable) { TDateTime LastUpdate = Elem.second->ReadTime("GLOBAL", "LastUpdate", TDateTime()); }
ちなみに、std::mapで定義している主なtypedef名は以下の通り。
型 | 説明 |
---|---|
key_type | キーの型 |
mapped_type | 値の型 |
value_type | キーと値の組み合わせ |
上記の例だと、key_typeがUnicodeString、mapped_typeがTIniFile*となる。