Rogue Wave バナー
前へマニュアルの先頭へ目次次へ

12.2 パラメータのないマニピュレータ

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) のいずれかです。

12.2.1 パラメータのないマニピュレータの例

パラメータのないマニピュレータとして、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 を参照し、同じストリームに対して参照を返す関数は、パラメータのないマニピュレータとして使用することができます。

12.2.2 マニピュレータ endl に関する注意

マニピュレータ endl は、ストリームに行末文字を挿入するときによく使用しますが、先に endl の実装で説明したように、endl には出力ストリームをフラッシュする機能もあります。ストリームのフラッシュは、時間がかかり、パフォーマンスも低下します。これが一般の状況で必要になることはありません。標準的な例を次に示します。

cout << "Hello world" << endl;

標準出力ストリーム cout は、標準入力ストリーム cin に結合されており、標準ストリームに対する入出力はいずれにしても同期されるため、フラッシュは必要ありません。フラッシュが必要ないので、本来の使用目的は行末文字の挿入ということになります。endl を入力するよりも '\n' を入力する方が面倒であれば、単純なマニピュレータの nl を追加することで行末文字が挿入されますが、ストリームのフラッシュは行われません。


前へマニュアルの先頭へ目次次へ

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


OEM リリース, 1998 年 6 月