数値文字列変換

何か文字列関連の話が多いですが,昨日に引き続き.


ログファイル等からデータを読み込むと,それらは最初は文字列として認識されています(文字列の"1000"など).そういう訳で,実際にそれらをデータとして扱うためには一旦データに変換しなければなりません.Cでは(C++でもそれなりに使っていますが),atoi(),atol(),atof()などの関数を使用してその変換を行っていましたが,これらの関数を利用する場合はあらかじめ変換後の型が分かっていなければなりません.そのため,テンプレートを使用したクラスを作成する場合にはこの問題がネックになってきます.


この悩みを解消するために,boostライブラリにはlexical_castと呼ばれるテンプレート関数が用意されています.これを用いると,例えば文字列の"1000"を整数に変換する場合には,

int a = boost::lexical_cast("1000");

という感じで記述でき非常に便利です.


それで,このlexical_castなんですが,結構簡単に実装できるんですね.Let's Boostで行われていた説明によると,

中では std::stringstream に << で流し込んで >> で取り出す、という形で実装されていますので、 標準のストリームI/Oに対応していてデフォルトコンストラクタ / コピーコンストラクタ / 代入演算子が正しく実装されているクラスなら、 何でも行けちゃいます。

だそうで.つまり,lexical_castは以下のような実装になっています.

#include 
#include 

template 
Type str_cast(Source& s) {
    std::stringstream ss;
    Type dest;
    
    ss << s;
    ss >> dest;
    
    return dest;
}

// テスト用
int main(int argc, char* argv[])
{
    std::string s = "1000";
    int n = str_cast(s);
    
    std::cout << n << std::endl;
    
    return 0;
}

実行結果:1000

実際には,ホワイトスペースやワイド文字,例外のことを考慮しているようなのでもう少し複雑になりますが,基本的にはこんな感じ.


ふたを開けてみるとちょっとしたものなのですが,すごく楽になることって結構ありますね.