iomanip.h に入っているマニピュレータの 1 つに setfill があります。setfill は、フィールド幅に詰め合わせる文字を設定するマニピュレータです。このマニピュレータは次の例に示すように実装されています。
//file setfill.cc #include<iostream.h> #include<iomanip.h> //the private manipulator static ios& sfill(ios& i, int f) { i.fill(f); return i; } //the public applicator smanip_int setfill(int f) { return smanip_int(sfill, f); }
引数付きマニピュレータは、2 つの部分から構成されます。
マニピュレータ。これは引数を 1 つ追加します。この前の例では、int 型の第 2 引数があります。このような関数に対するシフト演算子は定義されていないので、このマニピュレータ関数を入出力演算子のシーケンスに入れることはできません。そこで、マニピュレータの代わりに補助関数 (適用子) を使用する必要があります。
適用子。これはマニピュレータを呼び出します。適用子は大域関数で、そのプロトタイプをヘッダーファイルに入れておきます。マニピュレータは通常、適用子の入っているソースコードファイル内に静的関数として作成します。マニピュレータは適用子によってのみ呼び出されます。これを静的にした場合、その名前は大域アドレス空間の外側に保持されます。
ヘッダーファイル iomanip.h には、さまざまなクラスが定義されています。各クラスには、マニピュレータ関数のアドレスと 1 つの引数の値が入っています。iomanip クラスについては manip (3CC4) マニュアルページで説明されています。前の例では smanip_int クラスが使用され、これは ios で使用できます。ios で使用できるということは、istream と ostream でも使用できるということです。この例ではまた、int 型の第 2 引数を使用しています。
適用子は、クラスオブジェクトを作成してそれを返します。この前の例では、smanip_int というクラスオブジェクトが作成され、そこにマニピュレータと、適用子の int 型引数が入っています。ヘッダーファイル iomanip.h では、このクラスに対するシフト演算子が定義されています。入出力演算子シーケンスの中に適用子関数 setfill があると、その適用子関数が呼び出され、クラスが返されます。シフト演算子はそのクラスに対して働き、クラス内に入っている引数値を使用してマニピュレータ関数が呼び出されます。
次の例では、マニピュレータ print_hex は次の動作を行います。
このコード例は出力のみに使用されるため、クラス omanip_long が使用されます。これは int でなく long で動作します。
#include <iostream.h> #include <iomanip.h> static ostream& xfield(ostream& os, long v) { long save = os.setf(ios::hex, ios::basefield); os << v; os.setf(save, ios::basefield); return os; } omanip_long print_hex(long v) { return omanip_long(xfield, v); }