Boostを使おう


もくじ

はじめに

boost 1.33.0 VC 7.1を対象としています。

Boostとは「俺たちの野望は、ライブラリがSTLのようにC++の標準ライブラリになることだ」と言っている人達が作っているとても優秀なマルチプラットフォームライブラリです。

このページでで使う記法

$(boost_root)は、boostのインストールディレクトリを表します。Cドライブへboostを展開した人は、C:\boost_1_33_0が$(boost_root)になります。

$(vc71_root)は、VC7.1をインストールしたディレクトリになります。

$(ICU_root)は、ICUのインストールディレクトリになります。

正規表現ライブラリを使う

正規表現ライブラリを使うためには、まずライブラリをビルドする必要があります。とう事で、そうそうビルド。

1.33.0のregexライブラリに付属する、vc71.makファイルが正しくなく、nmakeを使ってビルドが出来ません。という事で、今回はbjamを使ってビルドします。bjamは、SourceForge、boostのダウンロードページの下の方にあるので持ってきておいてパスを通しておいてください。

コマンドプロンプトを開き、VC7.1のコマンドラインをパスに追加していない人は、$(vc71_root)\bin\vcvars32.batをコマンドプロンプトへドロップして、[Returnキー]で実行し、パスと環境変数の準備を行います。

$(boost_root)\libs\regex\buildへ移動。

以下のコマンドを実行し、ライブラリのインストールをします。

$(boost_root)\libs\regex\build>bjam -sTOOLS=vc-7_1 "-sBUILD=release debug <threading>single/multi <runtime-link>static/dynamic"

ICUを使う場合は

$(boost_root)\libs\regex\build>bjam -sICU_PATH=$(ICU_root) -sTOOLS=vc-7_1 "-sBUILD=release debug <threading>single/multi <runtime-link>static/dynamic"

すると、$(boost_root)\bin以下にターゲット毎に深い階層が作られて、ライブラリが作られます。実際に使うときは不便なので、bin以下の*.lib *.dllを検索し$(boost_root)\libfilesのフォルダを作り、そこに全て入れておきましょう。このパスをVCのライブラリのパスに追加すれば準備完了です。

使い方は、気が向いたら書いてみます。とりあえず、ビルドの覚え書きだけ。

日付(date_time)ライブラリを使う

日付ライブラリを使うためには、まずライブラリをビルドする必要があります。とう事で、そうそうビルド。

コマンドプロンプトを開き、VC7.1のコマンドラインをパスに追加していない人は、$(vc71_root)\bin\vcvars32.batをコマンドプロンプトへドロップして、[Returnキー]で実行し、パスと環境変数の準備を行います。

$(boost_root)\libs\date_time\buildへ移動。

以下のコマンドを実行し、ライブラリのインストールをします。

$(boost_root)\libs\date_time\build>bjam -sTOOLS=vc-7_1 "-sBUILD=release debug <threading>single/multi <runtime-link>static/dynamic"

すると、$(boost_root)\bin以下にターゲット毎に深い階層が作られて、ライブラリが作られます。実際に使うときは不便なので、bin以下の*.lib *.dllを検索し$(boost_root)\libfilesのフォルダを作り、そこに全て入れておきましょう。このパスをVCのライブラリのパスに追加すれば準備完了です。

使い方は、気が向いたら書いてみます。とりあえず、ビルドの覚え書きだけ。

lexical_castを使う

lexical_castとは、文字列と数値型(int doubleなど)を相互変換するライブラリです。これで、atoiや、sprintfを使わなくても簡単に変換が出来ます。

サンプルは以下の通り。変換に失敗した場合は、bad_lexical_cast例外が飛んできます。

#pragma warning(disable : 4514 4290)

#include <boost/lexical_cast.hpp>
#include <string>
#include <iostream>
#include <strstream>

using namespace std;
using namespace boost;

int main(int /* argc */, char** /* argv */)
{
    try
    {
        int data = 100;
        string result = lexical_cast<string>(data);
    
        cout << "int    : " << data << endl;
        cout << "result : " << result << endl;
    
        int reconvert = lexical_cast<int>(result);
        cout << "reconvert : " << reconvert << endl << endl;
    
        double doubleData = 3.1415;
        string doubleResult = lexical_cast<string>(doubleData);
    
        cout << "double : " << doubleData << endl;
        cout << "result : " << doubleResult << endl;
    
        double reconvertDouble = lexical_cast<double>(doubleResult);
        cout << "reconvert : " << reconvertDouble << endl;

        string error = "a";
        double not_cast = lexical_cast<double>(error);
    }
    catch(bad_lexical_cast& ex)
    {
        cout << ex.what() << endl;
    }

    return 0;
}

formatを使う

formatは、sprintfのC++版のようなものです。

printfと同じ文法もそのまま使えますし、拡張したフォーマットも出来るようです。

残念ながらドキュメントはなく、サンプルしかないようなので簡単に書いてみました。

まず、printfのような構文から。

#include <iostream>
#include <boost/format.hpp>

using namespace std;
using namespace boost;
using namespace boost::io;

int main()
{
    cout << format("%d") % 10;
    cout << endl;
    
    return 0;
}

文字列として取り出したいときは、

#include <iostream>
#include <boost/format.hpp>

using namespace std;
using namespace boost;
using namespace boost::io;

int main()
{
    string s;

    s = str(format ("数字 : %d 、文字 : %s") % 30 % "あああ");
    cout << s << endl;
    
    return 0;
}

拡張フォーマットは

#include <iostream>
#include <boost/format.hpp>

using namespace std;
using namespace boost;
using namespace boost::io;

int main()
{
    cout << format("%1% %2% %1%") % "1番目" % "2番目";
    cout << endl;
    
    return 0;
}

フォーマットに対しパラメータが多い場合は、too_many_args

フォーマットに対しパラメータが少ない場合は、too_few_args

例外がそれぞれ投げられます。

#include <iostream>
#include <boost/format.hpp>

using namespace std;
using namespace boost;
using namespace boost::io;

int main()
{
   // Too much arguments will throw an exception when feeding the unwanted argument :
    try
    {
        format(" %1% %1% ") % 101 % 102;
        // the format-string refers to ONE argument, twice. not 2 arguments.
        // thus giving 2 arguments is an error
    }
    catch (boost::io::too_many_args& exc)
    { 
        cerr <<  exc.what() << "\n\t\t***Dont worry, that was planned\n";
    }

    
    // Too few arguments when requesting the result will also throw an exception :
    try
    {
        cerr < format(" %|3$| ") % 101; 
        // even if %1$ and %2$ are not used, you should have given 3 arguments
    }
    catch (boost::io::too_few_args& exc)
    { 
        cerr <<  exc.what() << "\n\t\t***Dont worry, that was planned\n";
    }
    
    return 0;
}