web-dev-qa-db-ja.com

なぜC ++ STL iostreamは「例外にやさしい」ではないのですか?

Delphi VCLフレームワークに慣れています。そこでは、TStreamsがエラーで例外をスローします(たとえば、ファイルが見つからない、ディスクがいっぱいです)。代わりにC++ STLを使用するようにいくつかのコードを移植しており、デフォルトでは例外をスローしないiostreamによって検出されましたが、代わりに badbit/failbit flags を設定しています。

2つの質問...

a:これはなぜですか?初日から例外を組み込んで構築された言語の奇妙な設計上の決定のように思われますか?

b:これを回避する最善の方法は?期待どおりにスローするシムクラスを作成できましたが、これはホイールを再発明するようなものです。たぶんこれをより公正に行うBOOSTライブラリがあるのでしょうか?

46
Roddy

a。C++は初日を除いてビルドされませんでした。 「クラス付きC」は1979年に開始され、例外が1989年に追加されました。その一方で、streamsライブラリは1984年に作成されました(後で1989年にiostreamsになります(後でGNU 1991))では、最初は例外処理を使用できません。

参照:

b。あなたcanthe .exceptions method で例外を有効にします。

// ios::exceptions
#include <iostream>
#include <fstream>
#include <string>

int main () {
  std::ifstream file;
  file.exceptions ( ifstream::failbit | ifstream::badbit );
  try {
    file.open ("test.txt");
    std::string buf;
    while (std::getline(file, buf))
      std::cout << "Read> " << buf << "\n";
  }
  catch (ifstream::failure e) {
    std::cout << "Exception opening/reading file\n";
  }
  std::cout.flush();

  file.close();

  return 0;
}
69
kennytm

ケニーが言うように、必要に応じて例外を有効にすることができます。しかし、通常、I/Oはエラーが発生したときに何らかの種類の再開スタイルのプログラミングを必要としますが、例外を使用してこれをサポートすることは簡単ではありません。入力操作後のストリームの状態のテストははるかに簡単です。 I/Oで例外を使用するC++コードは実際には見たことがありません。

5
anon
  1. 例外をスローするときはいつでも、例外の安全性について考える必要があります。つまり、例外も例外も、例外安全の頭痛もありません。

  2. Iostreamも例外をサポートしています。ただし、例外のスローはオプションです。 exceptions (failbit | badbit | eofbit)を設定すると、例外を有効にできます

  3. Iostreamを使用すると、例外と予期しない動作の両方を楽しむことができます。

4
Neel Basu

では、「自分の質問に答える」時間です...

最初に、歴史のKennyTMに感謝します。彼が言うように、C++は[〜#〜](〜#〜]であり、初日からの例外を除いて設計されていたため、iostreamが「例外」であることは当然のことですその後、取り扱いが強化されました。

第二に、ニールBが指摘するように、入力フォーマット変換エラーに例外があることは大きな痛みです。 iostreamを単純なファイルシステムラッパーレイヤーとして検討していたので、これには驚かされました。そのケースについてはまったく考慮していませんでした。

第3に、BOOSTはパーティーに何かをもたらすようです Boost.IOStreams 。私が正しく理解していれば、これらはストリームの低レベルI/Oおよびバッファリングの側面を処理し、変換の問題を処理するために通常のc ++ IOStreamsライブラリを残します。 Boost.IOStreams 例外を使用します 私が期待する方法で。私がそれを正しく理解していれば、ケニーの例も次のようになります。

#include <ostream>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/stream.hpp>

int main () {
  boost::iostreams::stream_buffer <boost::iostreams::file_source> buf("test.txt");
  std::istream file(&buf);

  try {
    std::string buf;
    while (std::getline(file, buf))
      std::cout << "Read> " << buf << "\n";
  }
  catch (std::ios_base::failure::failure e) {
    std::cout << "Exception opening/reading file\n";
  }
  std::cout.flush();

  file.close();

  return 0;
}

このバージョンではthinkすると、「ファイルが見つかりません」などがスローされますが、 'istream'エラーはbadbit/failbitによって報告されます。

4
Roddy