原文

c++boost.gif (8819 bytes)Header boost/lexical_cast.hpp


Motivation

 例えば、int型のデータをstring型で表現させるときや、逆にstring型のインスタンスに格納された数値表現をint型に変換するなど、値を文字列の表現に変換しなければならないことがしばしばある。これらは、画面上の表示と設定ファイルの関係のように、プログラムの内部構造を外部に出力する際に良く用いられる手法である。

 C/C++標準ライブラリは、先に述べた変換機能の数々を提供するが、それらは使いやすさや拡張性、安全性の面においてまちまちである。

例として、atoiに代表されるC標準関数における多くの制限について述べてみよう :

 strtolに代表される標準C関数では、いくつかの基本的な制限が存在するものの、変換に関する素晴らしい制御方法を提供してくれる。しかし、普通、そのような制御方法は必要ではないし、使われることもない。scanfとその関連する関数では、さらに優れた制御方法を提供してくれるものの、安全性と使いやすさにおいて優秀とは言い難い。

 C++標準ライブラリは、ここで問題になっている種類のin-core 整形のためにstringstream を提供している。これは、文字列による、任意の型と入出力との間の変換と整形に関して幅広く管理する。しかし単純な変換に関して言えば、stringstream を直接利用するのは不格好(余計なローカル変数を取る必要があり、中置記法の利便性を失う)であるか、或いは不明瞭になりうる(stringstream オブジェクトが式の中で一時的オブジェクトとして作成される場合)。これは多くの面で、包括的な概念及びテキスト表現の管理能力を提供するが、これらは比較的高水準なので、単純な変換のためにも極端に多くのことを巻き込まなければならない。

 lexical_castテンプレート関数はテキストで表現可能な任意の型同士の変換を便利で一貫性のある形、簡単に言えば式レベルでの便利な変換を提供する。
 精度や書式においてlexical_castが標準で行うより柔軟な操作を必要とするとき、stringstreamの使用を推奨する。また、数値型間の変換を行う場合、numeric_castの方が適している。

 文字列ベースの表現に関する問題点等に関する議論を扱ったものとして、Herb Sutterの記事 The String Formatters of Manor Farmを紹介しておこう。これには、stringstreamlexical_cast等の比較も含まれている。


Examples

以下のサンプルではコマンドラインから与えられた複数の引数を数値の列に変換している。
int main(int argc, char * argv[])
{
    using boost::lexical_cast;
    using boost::bad_lexical_cast;

    std::vector<short> args;

    while(*++argv)
    {
        try
        {
            args.push_back(lexical_cast<short>(*argv));
        }
        catch(bad_lexical_cast &)
        {
            args.push_back(0);
        }
    }
    ...
}
以下のサンプルでは文字列の中に数値を埋め込んでいる。
void log_message(const std::string &);

void log_errno(int yoko)
{
    log_message("Error " + boost::lexical_cast<std::string>(yoko) + ": " + strerror(yoko));
}

Synopsis

ライブラリの詳細:"boost/lexical_cast.hpp"
namespace boost
{
    class bad_lexical_cast;
    template<typename Target, typename Source>
      Target lexical_cast(Source arg);
}
テストコード:"lexical_cast_test.cpp"

lexical_cast

template<typename Target, typename Source>
  Target lexical_cast(Source arg);
引数として受け取ったargstd::stringstreamに流し込み、Targetのデータに変換して返す。もし変換が失敗した場合、例外bad_lexical_castが発生する。

引数と戻り値の型の条件:

streamにおけるベースの文字型は、特にワイド文字を利用した変換を必要としない場合、char型を利用し、そうで無ければ、wchar_t型を利用する。ベースにワイド文字を必要とするのは、wchar_twchar_t *std::wstringである。

より高度な変換を必要とする場合、std::stringstreamおよびstd::wstringstreamを利用することをお勧めする。streamの機能の必要のない変換が要求されているのならば、lexical_castを利用することは適さない。そのような特殊なケースための準備をlexical_castは用意してないからである。


bad_lexical_cast

class bad_lexical_cast : public std::bad_cast
{
public:
    ... // std::exceptionと同様のメンバ関数を持つ
};
この例外はlexical_castが失敗したことを示すために使用される。

Changes


© Copyright Kevlin Henney, 2000, 2002

Japanese Translation Copyright (C) 2003 chy <chy@co2.ne.jp>

オリジナルの、及びこの著作権表示が全ての複製の中に現れる限り、この文書の複製、利用、変更、販売そして配布を認める。
このドキュメントは「あるがまま」に提供されており、いかなる明示的、暗黙的保証も行わない。
また、いかなる目的に対しても、その利用が適していることを関知しない。