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 &reg_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 &reg_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での変更点

  • 1バイト文字のpathと2バイト文字のwpathを,一つのクラスpathに統合.
  • pathクラスの新しいメンバ関数
    • has_stem() : ファイル名の最初から最後の"."までを抜き出したもの(stem()参照)がempty()ならfalseを返す.
    • has_extension() : ファイル名に拡張子があればtrue, なければfalseを返す.
    • is_absolute() : 絶対パスならtrue, 相対パスならfalseを返す.(同じ機能であったis_complete()は廃止)
    • is_relative() : is_absolute()の逆.
    • make_preferred() : パス文字列を使用している環境でのネイティブフォーマットに変換したものを返す. Windowsなら"/"(スラッシュ)はすべて"\"(バックスラッシュ or 円マーク)に置き換えられる.
  • boost::filesytem関数の変更,新規追加
    • absolute() : 絶対パスに変換.complete()を置き換える関数.
    • create_symlink() : シンボリックリンクを生成する関数.POSIXとWindows両方をサポートするようになった.
    • read_symlink() : 新規追加関数.シンボリックリンクの本体のパスを返す.
    • resize_file() : 新規追加関数.ファイルサイズ変更.
    • unique_path() : 新規追加関数.一時ファイル用のランダムなファイル名を生成する. たとえば,引数にpath("%-%")と指定すると"c463-8e59"のような0-9,a-fで構成されたファイル名が生成される.

詳しくはBoost Filesystem Version 3 - Introduction

Visual C++でのインストール

Visual C++用のバイナリがboostproで配布されている(要登録).

自身の環境でビルドしたい場合の手順は以下 (詳しくは,Getting Startedを参照).

  1. boostのページから最新のboostライブラリをダウンロードする. 中央のDOWNLOADSのところから最新版のリンクをクリックし,boost_1_57_0.zipなどをダウンロードして解凍する. 解凍先フォルダを$BOOSTとする.

[ver1.5?以降(バージョンはちゃんと確かめていない)]

  1. boostではビルドするためのBoost.Buildシステムを構築するためのバッチファイルbootstrapが含まれているので,これを実行する. スタートメニューからVisual Studioコマンドプロンプト (VS2012ならMicrosoft Visual Studio 2012 -> Visual Studio Tools -> VS2012 の開発者コマンド プロンプト) を立ち上げ,$BOOSTフォルダに移動し,以下のコマンドを実行すr.
    bootstrap
  2. Boost.Buildシステムが構築されたら以下のコマンドを実行
    .\b2
    ビルドオプションはb2 --helpで確認できる.例えばx64,multi-threadingで4スレッドでビルドの場合ならば,
    .\b2 threading=multi variant=debug,release address-model=64 -j 4
    となる.static,sharedはlink,runtime-linkオプション,作成されたライブラリファイルを置くフォルダ指定には--stagedirオプションを用いる.

[ver1.49?以前]

  1. bjam.exeを準備する.boostのページからビルド済みバイナリを落としてくるか, 自分で環境に合わせてビルドする.ビルドの仕方は以下.
    1. $BOOST\tools\jam\src\build.bat を実行する. bjamのソースコード(boost-jam-3.1.18.zipなど)をダウンロード解凍する.解凍したフォルダにあるbuild.batを実行する.何も指定しなければ自動で環境を判別する.環境を選択する場合は,コマンドプロンプトから,
      build.bat vc10
      などとする.vc10はVS2010, vc8にするとVS2005, vc9にするとVS2008.その他のtoolsetはBuilding BJamを参照.
    2. $BOOST\tools\jam\src\bin.ntx86\ に環境に合わせたbjam.exeができるので,これを$BOOSTかPATHが通っているところに移動.
  2. コマンドプロンプトで$BOOSTに移動して,bootstrap.batを実行.
    bootstrap.bat
  3. bjam.exeを実行する.オプションの例は以下.
    bjam.exe --toolset=msvc-10.0 --prefix=C:\usr\boost_1_45 --build-type=complete link=static release install
    オプションとして,
    • --toolset=msvc-10.0 : VS2010用,VS2005の場合はmsvc-8.0,VS2008の場合はmsvc-9.0
    • --prefix=C:\usr\boost_1_45 : インストール先.インクルードファイルとライブラリファイル(*.lib)などが置かれる.
    • --build-type=complete : 完全ビルド.デフォルトではminimalになっている.
    • link=static : スタティックリンクを指定(dllなし).共有リンクの場合はsharedを指定,両方指定(link=static,shared)も可
    • release : リリースビルド.デバッグビルドの場合はdebugを指定する.
    • install : ビルドしたファイル(*.dll, *.libなど)をprefixで指定したフォルダに移動する.
      を指定している.他のオプションの詳しい説明は bjam.exe --help で参照.ビルドは環境にもよるが結構時間がかかるので注意.
  4. prefixオプションで指定したところにinclude\boost-1_45, libフォルダができているので,それぞれインクルードパス,ライブラリパスに追加するなどする.

リンク


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2024-03-08 (金) 18:06:08