boostライブラリについて ライブラリ†boost::bind†個人的には一番よく使うのがboost::bind. STLのbind1st, bind2stの汎用版である.任意の引数をbindして,固定値にしたり,メンバ関数へのポインタもサポートする. #include <boost/bind.hpp> boost::bindは関数オブジェクトを作成することができるのだが,関数の引数をある値に固定することができる. 例えば, int func2(int x, int y) { return x+y; } int func3(int x, int y, int z) { return x+y+z; } void main(void) { boost::function<int (int, int)> func; func = func2; cout << func(1, 2) << endl; func = boost::bind(func3, _1, _2, 0); cout << func(1, 2) << endl; } のように,3引数を取る関数の最後の引数に渡す値を0に固定した関数の関数オブジェクトを簡単に作れる. また,下のboost::functionでも述べているが,メンバ関数についても下記のmem_fnと同様にできる. Class1 *obj = new Class1; boost::function<int (int)> func = boost::bind(&Class1::Func1, boost::ref(obj), _1); boost::mem_fn†#include<boost/mem_fn.hpp> メンバ関数を関数オブジェクトとして扱えるようにする.std::mem_fun,std::mem_fun_ref の一般化バージョンで引数の数は2個以上でも可能.std::for_eachにメンバ関数を渡したいときなどに便利. class MemClass { public: MemClass(int x) : a(x){} void Print(){ cout << a << endl; } private: int a; }; void main(void) { vector<MemClass> v; v.push_back(MemClass(1)); v.push_back(MemClass(2)); v.push_back(MemClass(3)); for_each(v.begin(), v.end(), boost::mem_fn(&MemClass::Print)); } boost::lexical_cast†#include<boost/lexical_cast.hpp> 文字列と値の変換を行う.C言語のitoaとかと同じ. double x = 0.0; std::string str; str = boost::lexical_cast<std::string>(x); x = boost::lexical_cast<double>(str); boost::format†#include<boost/format.hpp> printfに似たような感じの書式化処理をする. cout << boost::format("i : %1% - x=%2%, str=%3%") % 1 % 15.0 % "rml"; formatではformatオブジェクト(フォーマッタ)にオペレータ"%" で変数を食わせるため, boost::format frmt("i : %1% - x=%2%, str=%3%"); frmt % 1; frmt % 15.0; frmt % "rml"; でも可.std::stringではき出したい場合は,メンバ関数str()かboost::ioのstr(const format&)を用いる. std::string str; str = frmt.str(); str = boost::io::str(frmt); フォーマッタに別の変数を食わせる場合は,そのまま, frmt % 2; frmt % 20.0; frmt % "rml2"; と続ける. 書式指定に%1%,%2%・・・を用いる場合は並べ替えが可能. cout << boost::format("%2%, %1%, %3%, %1%") % 1 % 2 % 3; 出力は 2, 1, 3, 1 となる.並び替えが必要でないなら従来のprintf通りの書式指定を用いることもできる. cout << boost::format("%d, %s, %3.1f") % 1 % "2" % 3.0; 出力は 1, 2, 3.0 . boost::function†#include<boost/function.hpp> 汎用関数オブジェクト.関数ポインタも関数オブジェクトも両方とも格納できる. class FuncClass { public: FuncClass(int i, int j) : a(i), b(j) {} double Dot(int x, int y){ return sqrt((double)(a*x+b*y)); } int a, b; }; struct FuncObject { double operator()(int x, int y){ return sqrt((double)(x*x+y*y)); } }; double Func(int x, int y) { return sqrt((double)(x*x+y*y)); } とあった場合,関数ポインタ(Func(int x, int y))では, boost::function<double (int, int)> length = &Func; cout << boost::format("length = %f\n") % length(1, 2); で出力は,length = 2.236068 となる.function<double (int, int)>でdoubleが返値,(int, int)が引数を表している.コンパイラによっては,function2<double, int, int> と書かなければならないかも. 関数オブジェクト(FuncObject)は, length = FuncObject(); cout << boost::format("length = %f\n") % length(2, 3); 出力は,length = 3.605551 となる. クラスのメンバ関数を渡すときは,std::mem_fun と std::bind1st あたりを用いることができるが,ここでは2変数をとっているので boost::bind を用いる. FuncClass obj(3, 4); length = boost::bind(&FuncClass::Dot, boost::ref(obj), _1, _2); cout << boost::format("length = %f\n") % length(3, 4); 出力は,length = 5.000000 となる. boost::xpressive†#include <boost/xpressive/xpressive.hpp> 正規表現クラス.boost::regexと違ってlibファイルは必要ない. /*! * 正規表現に文字列がマッチするかどうかテスト * @param[in] str 文字列 * @param[in] reg_str 正規表現 * @return マッチしたらtrue */ static bool Match(const string &str, const string ®_str) { using namespace boost::xpressive; sregex reg = sregex::compile(reg_str); smatch m; if(regex_search(str, m, reg)){ return (m.str() == str); } else{ return false; } } /*! * 正規表現に文字列がマッチするかどうかテスト * @param[in] str 文字列 * @param[in] reg_str 正規表現 * @param[out] mch マッチした部分文字列 * @return マッチしたらtrue */ static bool Match2(const string &str, const string ®_str, vector<string> &mch) { using namespace boost::xpressive; sregex reg = sregex::compile(reg_str); smatch m; if(regex_search(str, m, reg)){ mch.resize(m.size()); for(int i = 0; i < (int)mch.size(); ++i){ mch[i] = m[i]; } return (m.str() == str); } else{ return false; } } boost::random†#include <boost/random.hpp> 様々な乱数を生成する.以下はメルセンヌツイスタで正規乱数,定分布乱数を生成するジェネレータの例. typedef boost::variate_generator< boost::mt19937, boost::uniform_real<> > rxRandMtUni; typedef boost::variate_generator< boost::mt19937, boost::normal_distribution<> > rxRandMtGen; /*! * 「メルセンヌツイスター」(Seed=現在時刻) で「正規乱数」を生成するジェネレータを返す * @param[in] _min 乱数の最小値 * @param[in] _max 乱数の最大値 * @return 「メルセンヌツイスター」(Seed=現在時刻) で「正規乱数」を生成するジェネレータ */ inline rxRandMtGen GenRandomGenerator(const double &_min, const double &_max) { boost::mt19937 gen0(static_cast<unsigned long>(time(0))); //boost::uniform_real<> dst0(_min, _max); boost::normal_distribution<> dst0(0, 0.01); rxRandMtGen rand0(gen0, dst0); return rand0; } /*! * 「メルセンヌツイスター」(Seed=現在時刻) で「定分布乱数」を生成するジェネレータを返す * @param[in] _min 乱数の最小値 * @param[in] _max 乱数の最大値 * @return 「メルセンヌツイスター」(Seed=現在時刻) で乱数を生成するジェネレータ */ inline rxRandMtUni GenRandomGeneratorMtUni(const double &_min, const double &_max) { boost::mt19937 gen0(static_cast<unsigned long>(time(0))); boost::uniform_real<> dst0(_min, _max); rxRandMtUni rand0(gen0, dst0); return rand0; } 使うときは, rxRandMtGen rand = GenRandomGenerator(0.0, 1.0); for(int i = 0; i < 100; ++i){ cout << rand() << endl; } など. boost::iostreams†#include <boost/iostreams/stream.hpp> #include <boost/iostreams/filtering_stream.hpp> #include <boost/iostreams/concepts.hpp> #include <boost/iostreams/operations.hpp> など. オリジナルのストリームを作成することができる. //! テキストストリーム - コマンドプロンプトに表示すると共にログファイルにも保存 class rxCout : public boost::iostreams::sink { string m_strLog; public: rxCout(string fn) { m_strLog = fn; } std::streamsize write(const char* s, std::streamsize n) { string str;//=s; str.resize(n); for(int i = 0; i < n; ++i){ str[i] = s[i]; } cout << str; boost::algorithm::replace_all(str, "\n", ""); static std::ofstream fsOut(m_strLog, std::ios::out); fsOut << str << endl; return n; } }; static boost::iostreams::stream<rxCout> RXCOUT("test.log"); //#define RXCOUT std::cout //! ファイルへのテキストストリーム class rxCoutFile : public boost::iostreams::sink { //std::ofstream m_fsOut0; public: rxCoutFile(bool enable) { //m_fsOut.open("log/sph.log", std::ios::out); } std::streamsize write(const char* s, std::streamsize n) { string str;//=s; str.resize(n); for(int i = 0; i < n; ++i){ str[i] = s[i]; } boost::algorithm::replace_all(str, "\n", ""); static std::ofstream fsOut("log/sph.log", std::ios::out); fsOut << str << endl; return n; } }; static boost::iostreams::stream<rxCoutFile> RXFOUT(true); 例のRXCOUTをcoutの代わりに使うことで出力内容を画面に表示すると共にファイルにも保存することができる. boost::filesystem†v3での変更点†
詳しくはBoost Filesystem Version 3 - Introduction. Visual C++でのインストール†Visual C++用のバイナリがboostproで配布されている(要登録). 自身の環境でビルドしたい場合の手順は以下 (詳しくは,Getting Startedを参照).
[ver1.5?以降(バージョンはちゃんと確かめていない)]
[ver1.49?以前]
リンク† |