Я нахожусь в процессе написания своей собственной выходной потоковой библиотеки, и я пытаюсь имитировать поведение std :: ostream, где оно не конфликтует с новым поведением, которого я пытаюсь достичь.В настоящее время я пытаюсь имитировать этот интерфейс, унаследованный от ios:
std::ostream::exceptions(ios::iostate state)
Согласно cplusplus.com :
"этот метод устанавливает новое исключениемаска для потока и очищает флаги состояния ошибки потока (как если бы вызывался член clear ()). "
Мне не было ясно, означает ли это, что все флаги будут сброшены или толькоони устанавливаются в маске исключений, поэтому я написал тестовую программу, но получил довольно неожиданные результаты.Вот программа:
#include <sstream>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
ostringstream oss;
try
{
cout << " badbit = " << ios::badbit << "\n";
cout << " eofbit = " << ios::eofbit << "\n";
cout << " failbit = " << ios::failbit << "\n\n";
cout << " oss.rdstate() = " << oss.rdstate() << "\n";
cout << " oss.exceptions() = " << oss.exceptions() << "\n\n";
cout << "executing: oss.setstate(ios::badbit | ios::failbit);" << "\n";
oss.setstate(ios::badbit | ios::failbit);
cout << " oss.rdstate() = " << oss.rdstate() << "\n";
cout << " oss.exceptions() = " << oss.exceptions() << "\n\n";
cout << "executing: oss.exceptions(ios::failbit);" << "\n";
oss.exceptions(ios::failbit);
cout << " oss.rdstate() = " << oss.rdstate() << "\n";
cout << " oss.exceptions() = " << oss.exceptions() << "\n";
}
catch(const exception& x)
{
cout << endl;
cout << "**** EXCEPTION THROWN ****" << "\n";
cout << argv[0] << ": " << x.what() << endl;
cout << " oss.rdstate() = " << oss.rdstate() << "\n";
cout << " oss.exceptions() = " << oss.exceptions() << "\n";
return 1;
}
catch(...)
{
cerr << argv[0] << ": unknown exception." << endl;
return 1;
}
return 0;
}
А вот и вывод:
matt@dworkin:~/dev/ostream/libs/ostream$ g++ --version
g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
matt@dworkin:~/dev/ostream/libs/ostream$ g++ --std=c++17 foo.cpp
matt@dworkin:~/dev/ostream/libs/ostream$ ./a.out
badbit = 1
eofbit = 2
failbit = 4
oss.rdstate() = 0
oss.exceptions() = 0
executing: oss.setstate(ios::badbit | ios::failbit);
oss.rdstate() = 5
oss.exceptions() = 0
executing: oss.exceptions(ios::failbit);
**** EXCEPTION THROWN ****
./a.out: basic_ios::clear: iostream error
oss.rdstate() = 5
oss.exceptions() = 4
Итак, основываясь на документах cplusplus.com, я не ожидал, что будет выдано исключение.И как видно из вывода, сгенерированного из обработчика исключений, никакие флаги состояния никогда не очищались.Так это ошибка компилятора, ошибка документации или я что-то упустил?
В качестве отступления, я предпочитаю поведение, демонстрируемое, по сравнению с документированным поведением.Мне кажется странным, что запрос об ошибках будет иметь побочный эффект удаления существующих ошибок.На самом деле я сначала реализовал его так же, как, очевидно, делает g ++ (при условии, что так будет работать наверняка), и только потом прочитал документы по этому методу.