## 4.4 ストリームのファセットの使用

`time_put` ファセットで日付を出力する応用例を示します。出力する日付を次のように定めます。

>     struct tm aDate;                                              //1

>     memset(aDate,0,sizeof aDate);                                 //2
>     aDate.tm_year = 1989;
>     aDate.tm_mon = 9;
>     aDate.tm_mday = 1;

>     cout.imbue(locale::locale("De_CH"));                          //3
>     cout << aDate;                                                //4

//1 | 日付オブジェクトを作成します。型は tm です。これは標準 C ライブラリで定義した時間構造体です。
//2 | 日付オブジェクトが 1989 年 9 月 1 日に初期化されます。
//3 | このプログラムの使用地域は、スイスのドイツ語圏の州ということにします。したがって、標準出力ストリームはドイツ-スイスロケールに組み込みます。
//4 | 日付がドイツ式で出力ストリームに出力されます。

出力結果: 1. September 1989

C ライブラリの時間構造体 tm のための演算子 <<() は、標準 C++ ライブラリには定義されていないため、挿入子を設定する必要があります。次のコードでこの方法を示します。入出力ストリームの詳細については、『標準 C++ ライブラリ・ユーザーズガイド』の入出力ストリームの節を参照してください。

複雑になることを防ぐため、書式設定時に生じる例外の送出処理は省略します。

>     template<class charT, class traits>
>     basic_ostream<charT, traits>&
>     operator<<(basic_ostream<charT,traits>& os, const tm& date)   //1
>     {
>      locale loc = os.getloc();                                    //2
>      typedef ostreambuf_iterator<charT,traits> outIter_t;         //3
>      const time_put<charT,outIter_t>& fac                         //4
>          = use_facet < time_put<charT, bufIter_t > > (loc);       //5
>      fac.put(os,os,os.fill(),&date,'x');                          //6
>      return os;
>     }

//1 | ストリーム挿入子の典型的な識別形式です。出力ストリームまでの参照と印刷するオブジェクトまでの固定参照を取り出し、同じストリームまでの参照を返します。
//2 | ストリームのロケールオブジェクトは、ストリームのメンバー関数 getloc() で得られます。このロケールオブジェクトに、求める時間書式ファセットオブジェクトがあるはずです。
//3 | ストリームバッファまでの出力反復子の型を定義します。 時間書式設定ファセットオブジェクトでは、書式設定した出力を反復子により出力コンテナに書き込みます (『標準 C++ ライブラリ・ユーザーズガイド』のコンテナと反復子の節を参照してください)。基本的に、これは文字列や C++ 配列などの出力反復子がある任意コンテナです。 ここでは、時間書式設定ファセットオブジェクトは、ストリームの書式設定層を経由せずに、出力ストリームの基本ストリームバッファに直接的に書き込むようにします。したがって、出力コンテナはストリームバッファになります。
//4 | ロケールオブジェクトの time_put ファセットオブジェクトまでの参照を保持する変数を定義します。時間書式設定ファセットクラス time_put には 2 つのテンプレートパラメータがあります。 最初のテンプレートパラメータは、出力に使用する文字型です。ストリームの文字型をテンプレート引数として指定します。 2 番目のテンプレートパラメータは、出力反復子型です。ここでは、以前に定義したストリームバッファ反復子型 outIter_t を指定します。
//5 | ストリームのロケールから、use_facet() によって時間書式設定ファセットオブジェクトを取り出します。
> //6 | ファセットオブジェクトの書式設定サービス put() が呼び出されます。どのような引数を使用するのかを確認してください。次に示すのは、関数のインタフェースです。
>     iter_type put  (iter_type      (a)
>                    ,ios_base&      (b)
>                    ,char_type      (c)
>                    ,const tm*      (d)
>                    ,char)          (e)
型の iter_type と char_type は、ファセットクラスのインスタンス化時にテンプレート引数を表す型です。この場合は、ostreambuf_iterator<charT,traits> と charT です。charT と traits は、それぞれテンプレート引数です。 実際の呼び出しは、次のようになります。 `nextpos = fac.put(os,os,os.fill(),&date,'x');` 次に、引数の意味を説明します。
a. | 最初のパラメータは、出力反復子になります。反復子はストリームの配下のストリームバッファに指定します。出力ストリームに対する参照 os は出力反復子に変換されます。出力ストリームバッファ反復子に、出力ストリームを取り出すコンストラクタ、すなわち basic_ostream<charT,traits>& があるためです。
b. | 2番目のパラメータの型は ios_base&です。ストリーム基底クラスの 1 つです。クラス ios_base には書式制御用のデータが保管されます (詳細については、入出力ストリームの節を参照してください)。ファセットオブジェクトでは、この書式設定情報を使用します。ここで、参照から出力ストリームまでの自動キャストを利用して、基底クラスまでの参照に、出力ストリームの ios_base 部を指定します。
c. | 3 番目のパラメータは、空白詰め文字です。出力を調整して空白を詰めるときに使用します。ストリームの fill() 関数を呼び出してストリームの空白詰め文字を指定します。
d. | 4 番目のパラメータは、C ライブラリの時間構造体 tm までのポインタです。
e. | 5 番目のパラメータは、C 関数 strftime() の場合と同じ書式設定文字です。x は、ロケールの適切な日付表現です。
f. | 返される値は、最後に挿入した文字の直後の位置を示す出力反復子です。

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

OEM リリース, 1998 年 6 月