Intro
sync_with_stdio, which is enabled by default states that internally C and C++ use the same buffer for their streams. But there is no interoperability beyond that. I can't for example construct a basic_rdbuf from a FILE, I need to use basic_rdbuf::open.
What I'm trying to do
I'd like to use exceptions with IO but there's a problem. It's true that you can use strerror to get the error message, but that's way down the stack. C++ IO only has one exception (failure) and it only has one error code (io_errc::stream). There is no granularity, so catching an exception far away from where the error actually occurred is not very helpful.
Here's another problem. You can configure it to throw exceptions on failbit. But not all failbit errors are exceptions. Example:
try
{
filestr.open(":^(");
if (!(file >> input))
{
// error
}
}
catch (ios_base::failure& e)
{
cout << strerror(errno);
}
This groups "bad user input" with "file does not exist", which I think is bad design.
Ideally I'd like to have separation of concerns. Something like:
try
{
auto file = std::fopen(...);
if ( /* bad conditional */ )
throw custom_exception_with_error_code(errno);
} catch (custom_exception_with_error_code& e)
{
if (e.code() == some_error_code)
{
/* handle error */
}
}
auto stream = std::some_something_that_accepts_file(file);
/* ... */
This is just a rough sketch. I'm working out the details.
The moral
I'd ideally like to not have to start writing bulky custom stream classes from scratch. I'm looking for a friendly built-in way to do this. Is it possible?
I'm also looking for advice on flaws with my approach.
Aucun commentaire:
Enregistrer un commentaire