endl のようにパラメータのないマニピュレータは、マニピュレータの最も単純な形式です。マニピュレータ型 manipT は関数ポインタ型であり、マニピュレータ Manip は関数ポインタです。付属関数 fmanipT() はポイント先の関数です。
入出力ストリームでは、次の関数ポインタ型がマニピュレータとして機能します。
(1) ios_base& (*pf)(ios_base&) (2) basic_ios<charT,Traits>& (*pf)(basic_ios<charT,Traits>) (3) basic_istream<charT,Traits>& (*pf)(basic_istream<charT,Traits>) (4) basic_ostream<charT,Traits>& (*pf)(basic_ostream<charT,Traits>)
マニピュレータ関数の識別形式は、上記の例以外にもあります。ユーザー定義のシステム型を作成した場合は、さらに別の識別形式をマニピュレータとして使用することができます。
上記に示した 4 つのマニピュレータ型では、多重定義された必要な挿入子とメンバー関数が、ストリームクラスですでに提供されています。 入力ストリームの場合、次のような抽出子になります。
template<class charT, class traits> basic_istream<charT, traits>& basic_istream<charT, traits>::operator>> (basic_istream<charT,traits>& (*pf)(input_stream_type&) ) { return (*pf)(*this);..}
ここで、input_stream_type は、関数ポインタ型 (1) から (3) のいずれかです。
同様に、出力ストリームについては、次のような抽出になります。
template<class charT, class traits> basic_ostream<charT, traits>& basic_ostream<charT, traits>::operator<< (basic_ostream<charT, traits>& (*pf)(output_stream_type& )) { return (*pf)(*this); }
ここで、output_stream_typeは、関数ポインタ型 (1)、(2)、(4) のいずれかです。
パラメータのないマニピュレータとして、endl を例として挙げます。マニピュレータ endl は、出力ストリームにだけ使用しますが、(4) の型の関数に対するポインタです。
template<class charT, class traits> inline basic_ostream<charT, traits>& endl(basic_ostream<charT, traits>& os) { os.put( os.widen('\n') ); os.flush(); return os; }
次の式は、
cout << endl;
次のように挿入子に対する呼び出しになります。
ostream& ostream::operator<< (ostream& (*pf)(ostream&))
endl は、pf の実際の引数となります。つまり、cout << endl; は cout.operator<<(endl) と同じです。
次に、もう 1 つのマニピュレータ、boolalpha を例に挙げます。これは、入力ストリームおよび出力ストリームに適用することができます。マニピュレータ boolalpha は、(1) の型の関数に対するポインタです。
ios_base& boolalpha(ios_base& strm) { strm.setf(ios_base::boolalpha); return strm; }
注: ios_base、basic_ios、basic_ostream、または basic_istream を参照し、同じストリームに対して参照を返す関数は、パラメータのないマニピュレータとして使用することができます。
マニピュレータ endl は、ストリームに行末文字を挿入するときによく使用しますが、先に endl の実装で説明したように、endl には出力ストリームをフラッシュする機能もあります。ストリームのフラッシュは、時間がかかり、パフォーマンスも低下します。これが一般の状況で必要になることはありません。標準的な例を次に示します。
cout << "Hello world" << endl;
標準出力ストリーム cout は、標準入力ストリーム cin に結合されており、標準ストリームに対する入出力はいずれにしても同期されるため、フラッシュは必要ありません。フラッシュが必要ないので、本来の使用目的は行末文字の挿入ということになります。endl を入力するよりも '\n' を入力する方が面倒であれば、単純なマニピュレータの nl を追加することで行末文字が挿入されますが、ストリームのフラッシュは行われません。
Copyright (c) 1998, Rogue Wave Software, Inc.
このマニュアルに関する誤りのご指摘やご質問は、電子メールにてお送りください。
OEM リリース, 1998 年 6 月