[解決済み] std::flushはどのように機能するのですか?
質問
どなたか、次のようなことを (できれば平易な英語で) 説明していただけないでしょうか。
std::flush
がどのように機能するのかを説明していただけませんか?
- それは何ですか?
- ストリームを流すのはいつですか?
- なぜそれが重要なのですか?
ありがとうございました。
どのように解決するのですか?
回答がないため
何
std::flush
がたまたまそうであっただけで、実際にはどうなのかについて、ここで詳しく説明します。
std::flush
は
マニピュレーター
つまり、特定のシグネチャを持つ関数です。まず最初に、簡単な例として
std::flush
というシグネチャを持つ
std::ostream& std::flush(std::ostream&);
しかし、現実はもう少し複雑です(興味のある方は、以下でも解説しています)。
ストリームクラスのオーバーロード出力演算子は、このような形式の演算子を取ります。つまり、マニピュレータを引数に取るメンバ関数が存在します。出力演算子は、オブジェクトそのものを使ってマニピュレータを呼び出す。
std::ostream& std::ostream::operator<< (std::ostream& (*manip)(std::ostream&)) {
(*manip)(*this);
return *this;
}
つまり、"output"すると。
std::flush
を
std::ostream
を指定した場合、対応する関数を呼び出すだけであり、つまり、以下の2つの記述は等価である。
std::cout << std::flush;
std::flush(std::cout);
今すぐ
std::flush()
自体はかなり単純です。このメソッドが行うのは
std::ostream::flush()
を呼び出すだけです。つまり、次のような実装を想定してください。
std::ostream& std::flush(std::ostream& out) {
out.flush();
return out;
}
は
std::ostream::flush()
関数は、技術的には
std::streambuf::pubsync()
を呼び出します。ストリームバッファは、文字をバッファリングし、使用中のバッファがオーバーフローしたときや、内部表現が外部の宛先と同期されるべきとき、つまりデータがフラッシュされるときに、文字を外部の宛先に送信する役割を担います。シーケンシャルストリームでは、外部送信先との同期とは、バッファリングされた文字が直ちに送信されることを意味するだけである。つまり
std::flush
を使うと、ストリームバッファはその出力バッファをフラッシュします。たとえば、コンソールにデータが書き込まれたとき、フラッシュするとコンソールのこの位置に文字が表示されます。
ここで疑問が湧くかもしれません。なぜ、文字はすぐに書き込まれないのでしょうか? 簡単な答えは、文字の書き込みは一般的にかなり遅いということです。しかし、妥当な量の文字を書き込むのにかかる時間は、1 つの場所だけを書き込むのと本質的に同じです。OSやファイルシステムなどの特性にもよりますが、4k文字程度までなら1文字とほぼ同じ時間で書けることが多いです。したがって、外部の宛先の詳細に応じてバッファを使用して文字を送信する前にバッファリングすることは、大きなパフォーマンスの改善になります。
以上、3つの質問のうち2つにお答えしました。残りの質問は、「いつストリームをフラッシュするのか」です。答えはこうです。文字が外部の宛先に書き込まれるべき時です! これは、ファイル書き込みの終了時 (ファイルを閉じると暗黙のうちにバッファがフラッシュされます) か、ユーザ入力を要求する直前 (ただし
std::cout
から読み込むときに自動的にフラッシュされます)。
std::cin
として
std::cout
は
std::istream::tie()
になります。
std::cin
). 明示的にストリームをフラッシュしたい場合もあるかもしれませんが、それはかなりまれなことだと思います。
最後に、私が約束したのは
std::flush
が実際にどのようなものであるかを説明することを約束しました。ストリームは、異なる文字型を扱うことができるクラステンプレートです (実際に動作するのは
char
と
wchar_t
といった具合に、他の文字と組み合わせて使うことは、かなり難しいのですが、本当に決心すれば可能です。) を使用できるようにするには
std::flush
をストリームのすべてのインスタンスで使用できるようにするには、次のようなシグネチャを持つ関数テンプレートにする必要があります。
template <typename cT, typename Traits>
std::basic_ostream<cT, Traits>& std::flush(std::basic_ostream<cT, Traits>&);
を使う場合
std::flush
のインスタンス化ですぐに
std::basic_ostream
のインスタンス化であっても、それは本当に重要ではありません。コンパイラは自動的にテンプレート引数を推論します。しかし、この関数がテンプレート引数の推論を容易にする何かと一緒に言及されていない場合、コンパイラはテンプレート引数の推論に失敗します。
関連
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] C++で仮想関数が必要な理由とは?
-
[解決済み] 8192個の要素にループをかけると、プログラムが遅くなるのはなぜですか?
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】なぜC++プログラマは'new'の使用を最小限に抑えなければならないのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】C++ 式はポインタからオブジェクトへの型を持っている必要があります。
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み】C++のコードを終了させる方法