## 12.1 マニピュレータの復習

7.3 節のマニピュレータの例では、次のことを学習しました。

- マニピュレータは、ストリームに対して挿入や抽出のできるオブジェクトである。
- このような挿入や抽出には、有効な副作用がある。

ここでは、復習のために、マニピュレータの典型的な使用例を 2 つ紹介します。

>     cout << setw(10) << 10.55 << endl;

挿入したオブジェクト `setw(10)` と `endl` は、マニピュレータです。副作用として、マニピュレータ `setw(10)` では、ストリームのフィールド幅が `10` に設定されます。同様に、マニピュレータ `endl` では、行末文字が挿入され、出力がフラッシュされます。

先にも述べたように、拡張機能は入出力ストリームの最も重要な特長です。11.3 節では、組み込み型の入出力演算のように機能する、ユーザー定義型への挿入子と抽出子の実装方法を学びました。また、入出力枠組みに円滑に融合できるユーザー定義のマニピュレータを追加することもできます。この節では、その方法を説明します。

マニピュレータの挿入や抽出にあたっては、マニピュレータが `manipT` という型のオブジェクトである必要があります。また、それに対して、シフト演算子の多重定義バージョンがあることが条件です (マニピュレータ型 `manipT` の付属として、通常は `fmanipT()` という関数があります。詳細は後で説明します)。次に示すのは、マニピュレータ抽出子のパターンです。

>     template <class charT, class Traits>
>     basic istream<charT,Traits>&
>     operator>> (basic istream<charT,Traits>& istr
>                ,const manipT& manip)
>     {   return fmanipT(istr, );   }

この抽出子を定義することで、マニピュレータ `Manip` を抽出することができます。これは `manipT` 型のオブジェクトであり、次のようにして呼び出します。

>     cin >> Manip;

これを実行すると、前述の `operator>>()` が呼び出されます。マニピュレータ挿入子の場合も同様です。

マニピュレータの副作用は、一般に付属関数 `fmanipT()` を呼び出して作成します。この付属関数は、入力としてストリームを取り、ストリームを返します。マニピュレータ型 `manipT` を関数 `fmanipT()` に関連付ける方法はいくつかあります。関数 `fmanipT()` については、後の節で説明します。入出力枠組みでは、マニピュレータを実装する方法を指定するのではありません。代わりに、`smanip` という基底クラスがあり、これでユーザー定義のマニピュレータを派生させることができます。この手法については、他の有用なアプローチと共に説明します。

`width(10)` のようなパラメータ付きマニピュレータと、`endl` のようなパラメータなしマニピュレータでは大きな違いがあります。まず、パラメータなしマニピュレータの簡単な例を挙げます。

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

OEM リリース, 1998 年 6 月