これらはストリーム挿入(またはの場合は抽出)と呼ばれ、istream >>
実際には左シフト演算子と右シフト演算子のセマンティックオーバーロードです。
したがって、この:
int x = 1 << 1;
少しシフトですが、これは:
std::cout << x;
ストリーム挿入です。次のように明示的に書き出すことができます。
operator <<(std::cout, x);
まったく同じ結果が得られます。ストリーム挿入演算子の従来の形式(ユーザー定義型ではオーバーロードされる可能性があるため、独自の演算子を作成することは珍しくありません)は次のとおりです。
std::ostream& operator <<(std::ostream&, T value);
出力ストリームは(参照により)返されるため、呼び出しを連鎖させることができます。例は次のように変換されます。
operator<< (
operator<< (
operator<<(std::cout, "firstvalue"),
firstvalue
),
std::endl
);
ああ、そして... std::cout
(std::cerr
など)は関数ではありません:それらはグローバルオブジェクトです。ここでの関数は、オーバーロードされた<<
演算子です。FILE *stdout, *stderr
それらを同等のものと考えてください。
printf
etよりもC++iostreamsにはいくつかの利点があります。al:
- 型安全性:オーバーロード解決によりコンパイル時
"%f"
に関数が自動的に選択されるため、誤って整数を出力してガベージを取得することはできません。std::ostream& operator<<(std::ostream&, double)
- ユーザー定義型のサポート:ウィジーな新しいクラスのストリーム挿入演算子を記述でき、どこでも機能します
- ストリームの抽象化:同じオーバーロードを使用して(1回だけ書き込む)、stdoutとstderr(
cout
/ cerr
)、およびファイル(std::ofstream
)と文字列(std::ostringstream
)にフォーマットできます。printf
//を個別にfprintf
処理する必要はありません。snprintf
いくつかの欠点もあります。
- パフォーマンス:すべての抽象化と、実行時に構成されるロケールシステムの一般性にはいくらかのペナルティがあります
- 冗長性:少なくとも、ですでにサポートされているプリミティブ型
printf
の場合、フォーマット文字列ははるかに簡潔で表現力に富んでいます。