数値文字列の相互変換
ログファイル等からデータを読み込むと,それらは最初は文字列として認識されています (文字列の"1000"など).したがって,実際にそれらをデータ(数値)として扱うためには, 一旦データに変換しなければなりません.Cでは(C++でもそれなりに使っていますが), atoi(),atol(),atof()などの関数を使用してその変換を行っていましたが, これらの関数を利用する場合には,あらかじめ変換後の型が分かっていなければなりません. そのため,テンプレートを使用したクラスを作成する場合には,この問題がネックになってきます.
この悩みを解消するために,boostライブラリにはlexical_castと呼ばれるテンプレート関数が 用意されています.これを用いると,例えば文字列の"1000"を整数に変換する場合には,
int a = boost::lexical_cast<int>("1000");
と言った形式で記述するで事がき,非常に便利です.
このlexical_castというテンプレート関数ですが,かなり用意に実装することができるようです.
中では std::stringstream に << で流し込んで >> で取り出す、 という形で実装されていますので、 標準のストリームI/Oに対応していてデフォルトコンストラクタ / コピーコンストラクタ / 代入演算子が正しく実装されているクラスなら、 何でも行けちゃいます。
つまり,lexical_castは以下のような実装になっています.
#include <iostream>
#include <sstream>
template <class Type, class Source>
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<int>(s);
std::cout << n << std::endl;
return 0;
}
実際には,ホワイトスペースやワイド文字,例外のことを考慮しているようなので, もう少し複雑になりますが,基本的にはこんな感じです.蓋を開けてみるとちょっとしたものが, すごく便利なものになるという良い例だと思います.