Почему является C++ STL iostreams не “дружественное исключение”?

Я привык к Delphi Платформа VCL, где TStreams выдают исключения на ошибках (например, файл, не найденный, полный диск). Я портирую некоторый код для использования C++ STL и ловился iostreams, НЕ выдающим исключения по умолчанию, но устанавливающим badbit/failbit флаги вместо этого.

Два вопроса...

a: Почему это - Это кажется нечетным проектным решением для языка, созданного за исключениями в нем со дня один?

b: Как лучше всего избежать этого? Я мог произвести классы контейнера, которые бросают, как я ожидал бы, но это испытывает желание изобретать велосипед. Возможно, существует библиотека BOOST, которая делает это более нормальным способом?

45
задан Roddy 27 August 2013 в 11:02
поделиться

4 ответа

а. C ++ не создавался с исключениями с первого дня. «C с классами» появился в 1979 году, а исключения были добавлены в 1989 году. Между тем, библиотека streams была написана еще в 1984 году (позже стала iostreams в 1989 году (позже переопределена GNU) в 1991 году)), он просто не может использовать обработку исключений вначале.

Ссылка:

b. Вы можете включить исключения с помощью метода .exceptions .

// 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
ответ дан 26 November 2019 в 21:16
поделиться

Как говорит Кенни, вы можете включить исключения, если хотите. Но обычно ввод-вывод требует определенного стиля программирования при возникновении ошибки, что нелегко поддержать с помощью исключений - тестирование состояния потока после операции ввода намного проще. На самом деле я никогда не видел кода C ++, который использовал бы исключения для ввода-вывода.

5
ответ дан 26 November 2019 в 21:16
поделиться
  1. Каждый раз, когда вы генерируете исключение, вы должны думать о безопасности исключений. Так что никаких исключений, никаких исключений, никакой головной боли, связанной с безопасностью исключений.

  2. Iostreams также поддерживают исключения. Но бросать исключение необязательно. Вы можете включить исключение, установив exceptions (failbit | badbit | eofbit).

  3. Iostreams позволяют поддерживать как исключительное поведение, так и поведение без ожиданий.

4
ответ дан 26 November 2019 в 21:16
поделиться

Ладно, настало время "Ответить на свой вопрос"...

Во-первых, спасибо KennyTM за историю. Как он говорит, C++ был НЕ разработан с исключениями с первого дня, поэтому неудивительно, что обработка "исключений" в iostreams была прикручена позже.

Во-вторых, как отмечает Нил Б, наличие исключений при ошибках преобразования формата ввода было бы большой проблемой. Это удивило меня, потому что я рассматривал iostreams как простой слой обертки файловой системы, и я вообще не рассматривал этот случай.

В-третьих, похоже, что BOOST действительно привносит что-то новое: Boost.IOStreams. Если я правильно понимаю, они занимаются низкоуровневым вводом/выводом и буферизацией потоков, оставляя обычную библиотеку 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;
}

Я думаю, что в этой версии такие вещи, как "файл не найден" должны отбрасываться, но ошибки 'istream' будут сообщаться badbit/failbit.

4
ответ дан 26 November 2019 в 21:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: