## 4.5 標準ファセットの動作の変更

ロケールのファセットオブジェクトは、必要に応じて、別の種類のファセットオブジェクトと置き換えることができます。次の例では、標準ファセットクラスの 1 つである numpunct をもとに、標準 numpunct ファセットオブジェクトを新しいインスタンスに置き換え、ロケールオブジェクトを作成します。

ここで、ブール値の出力時に、値を "true" と "false" による数値で表現するか、英数字で表現するかを決定する必要があります。

>     int main(int argc, char** argv)
>     {
>        bool any_arguments = (argc > 1);                           //1
>        cout.setf(ios_base::boolalpha);                            //2
>        cout << any_arguments << '\n';                             //3
>        //
>     }

//1 | 型がブールである変数を定義します。初期値は、論理式のブール値です (argc > 1)。したがって、変数 any_arguments には、プログラムを引数付きで呼び出すか、引数なしで呼び出すかを指定した情報を含みます。
//2 | 書式フラグ ios_base:: boolalpha は、定義済みの出力ストリーム cout で設定されたセットです。その結果、ブール値はデフォルトの数値表現の 0 や 1 ではなく、文字列表現で出力されます。
//3 | ここで、文字列の "true" か "false" が出力されます。

文字列の表現は言語によって異なります。したがって、ロケールでは、ブール値を英数字の表現で提供します。それが、数値の書式設定に関わる文化的な規約を記述するロケールにある numpunct ファセットです。真か偽のブール値の文字列表現を返すサービスもここにあります。

次に示すのは、ファセット numpunct のインタフェースです。

>     template <class charT>
>         class numpunct : public locale::facet {
>         public:
>           typedef charT               char_type;
>           typedef basic_string<charT> string_type;
>           explicit numpunct(size_t refs = 0);
>           string_type  decimal_point()   const;
>           string_type  thousands_sep()   const;
>           vector<char> grouping()        const;
>           string_type  truename()        const;
>           string_type  falsename()       const;
>           static locale::id id;
>     };

次に、このファセットを別のファセットで置き換えます。さらに効果を高めるために、言語を変更するだけでなく、真と偽の単語も Yes! と No! などに変更してみましょう。別の言語を使用するだけならば、新しいファセットを使用する必要はありません。適切なネイティブロケールを使用すれば、それに対応するファセットが含まれるからです。

>     template <class charT>                                         //1
>     class change_bool_names
>         : public numpunct_byname<charT>                            //2
>     {
>      public:
>       typedef basic_string<charT> string_type;
>       explicit change_bool_names (const char* name,                //3
>           const charT* t, const charT* f, size_t refs=0)
>           : numpunct_byname<charT> (name,refs),
>             true_string(t), false_string(f) { }
>      protected:
>       string_type do_truename () const { return true_string; }     //4
>       string_type do_falsename () const { return false_string; }
>      private:
>       string_type true_string, false_string;
>     };

//1 | 新しいファセットは、テンプレートパラメータとして文字型を取り出すクラステンプレートです。
//2 | 新しいファセットは、 numpunct_byname<charT> ファセットから派生させます。 byname ファセットは、個々のロケール情報を C ロケールの外部表現から読み取ります。byname ファセットの作成に必要な名前は、setlocale() の呼び出しに使用するロケールの名前です。
//3 | `true` と `false` のアルファバージョンに表示するロケール名と、新しい値を設定するコンストラクタが呼び出されます。4 番目のパラメータ `refs` は、先の節で説明したように、ファセットの寿命を制御します。
//4 | 仮想メンバー関数 do_truename() と do_falsename() が再実装されます。これらは、公開メンバー関数の truename() と falsename() で呼び出します。詳細は、『標準 C++ クラスライブラリ・リファレンス』を参照してください。

次に、ドイツ語ロケールを作成します。図 11に示すように、`numpunct<char>` ファセットは、新しく作成した派生ファセット型のオブジェクトに置き換わります。

#### 図 11 -- numpunct<char> ファセットオブジェクトの置換

コードを示します。

>     void main(int argc, char** argv)
>     {
>       locale loc(locale("de_DE"),                                 //1
>            new change_bool_names<char>("de_DE","Ja.","Nein."));   //2
>       cout.imbue(loc);                                            //3
>       cout << "Argumente vorhanden? "  //Any arguments?
>            << boolalpha << (argc > 1) << endl;                    //4
>     }

//1 | ロケールオブジェクトは、新しいファセットクラスのインスタンスで構築されます。ロケールオブジェクトには、ドイツ語ロケールオブジェクトにあるすべてのファセットオブジェクトが設定されます。ただし、新しいファセットオブジェクト change_bool_names が numpunct ファセットオブジェクトの代わりに追加されます。
//2 | 新しいファセットオブジェクトには、ドイツ語 numpunct ファセットオブジェクトからすべての情報が適用され、真と偽のデフォルトのネイティブ名は、指定された文字列 "Ja."("Yes.") と "Nein."("No.") に置き換わります。
//3 | 標準出力ストリーム cout は、新しく作成したロケールに組み込まれます。
//4 | 式 (argc > 1) では、ブール値が算出され、これでプログラムを呼び出すときに引数を指定するかどうかを指定します。標準出力ストリームには、ブール値の英数字表現が出力されます。出力例を次に示します。 `Argument vorhanden? Ja.`

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

OEM リリース, 1998 年 6 月