Rogue Wave バナー
前へマニュアルの先頭へ目次次へ

4.3 ロケールのファセットへのアクセス

ロケールオブジェクトは、コンテナやマップのようなものですが、正確に処理するために、コンパイル時に型によってインデックス付けされます。そのため、インデックス演算子は演算子 [] ではなく、テンプレート演算子 <> を使用します。ロケールオブジェクトのファセットオブジェクトにアクセスするには、2 つのメンバー関数テンプレート use_facet と has_facet を使用します。

template <class Facet> const Facet&     use_facet(const locale&);
template <class Facet> bool             has_facet(const locale&);

以下のコードは、その使用方法を示したものです。これは ctype ファセットの利用方法の例です。文字列の中で、標準入力ストリームから読み取った文字列の大文字は小文字に変換され、標準出力ストリームに書き込まれます。

string in;
cin >> in;
if (has_facet< ctype<char> >(locale()))               //1
{  cout << use_facet< ctype<char> >(locale())         //2
               .tolower(in.begin(),in.end());         //3
}
//1 has_facet<...>() に対する呼び出しで、テンプレート引数により基底ファセットクラスを指定します。ロケールオブジェクトにこの型のファセットがない場合は、偽が返ります。
//2 関数テンプレート use_facet<>() は、指定した基底ファセット型のロケールのファセットオブジェクトを返します。ロケールオブジェクトは不変なので、このロケールオブジェクトの寿命が続く限り参照は有効です。指定した型のファセットがロケールにない場合は、use_facet により runtime_error 例外の送出が返ります。
//3 ファセットオブジェクトのメンバー関数 tolower() を呼び出します。これは C 関数 tolower() の機能です。文字列の大文字をすべて小文字に変換します。

この例では、ctype<char> は標準ファセットなので、has_facet に対する呼び出しは実際には必要ありません。各ロケールには、常に標準ファセットがすべて含まれるため、has_facet<ctype<char> > では常に true が返ります。ただし、has_facet() に対する呼び出しは、この章で前述した mythical ファセットなど、すべてのロケールにあるとは限らない非標準ファセットの処理に有用です。

use_facet 呼び出しと has_facet 呼び出しのコーディングでは、テンプレートパラメータのファセット型には、必ず基底ファセット型を指定してください。派生ファセット型は指定しないでください。次のコードはエラーになります。

locale loc;
const numpunct_byname<char> &np =             // エラー、基底ファセット型ではなく
      use_facet<numpunct_byname<char> >(loc); // インスタンス化された
                                              // use_facet

ファセット型や使用するコンパイラにもよって異なりますが、このコードは、おそらくコンパイル時エラーになります。エラーにならない場合には、予想外の実行時動作が発生することがあります。use_facet 呼び出しでは、numpunct_byname<char> 型 のスロットを占めるファセットが返ります。しかし、実際には先にも説明たように、これは基底ファセット型 numpunct<char> のスロットの場合も同じです。したがって、上記のコードでは、np は、実際には型が numpunct_byname<char> ではないオブジェクトに対する参照として初期化されます。

このようなエラーを防ぐには、 use_facethas_face だけを基底ファセット型で、すなわち、静的 locale::id メンバーを含むファセット型でインスタンス化してください。

locale loc;
const numpunct<char> &np =                      // 正しい
      use_facet<numpunct<char> >(loc);

前へマニュアルの先頭へ目次次へ

Copyright (c) 1998, Rogue Wave Software, Inc.
このマニュアルに関する誤りのご指摘やご質問は、電子メールにてお送りください。


OEM リリース, 1998 年 6 月