A quote from C++11 standard:
19.5.1.5 Error category objects [syserr.errcat.objects]
const error_category& system_category() noexcept;
4 Remarks: The object’s equivalent virtual functions shall behave as specified for class error_- category. The object’s name virtual function shall return a pointer to the string "system". The object’s default_error_condition virtual function shall behave as follows: If the argument ev corresponds to a POSIX errno value posv, the function shall return error_- condition(posv, generic_category()). Otherwise, the function shall return error_condition(ev, system_category()). What constitutes correspondence for any given operating system is unspecified. [ Note: The number of potential system error codes is large and unbounded, and some may not correspond to any POSIX errno value. Thus implementations are given latitude in determining correspondence. —end note ]
In other words the code below on some OSes may not work because the system_category().default_error_condition()
did not do the proper mapping to generic_category()
condition (which is fully allowed by the standard):
try
{
// do some file IO
}
catch(const std::system_error& e)
{
if(e.code() == std::errc::permission_denied) //...
}
The only solution would be to implement your own custom replacement for generic_category()
with mapping for all the OS codes you require (for all the OSes you need).
enum my_errc { /*...*/, access_denied };
class my_generic_category : public std::error_category
{
virtual bool equivalent(const error_code& code, int condition) const noexcept
{
#ifdef _WIN32
if(code == std::error_code(ERROR_ACCESS_DENIED, std::system_category())
return condition == my_errc::access_denied;
#elseif SOME_OTHER_OS // ...
}
// ...
And then use your own category instead of generic_category
:
catch(const std::system_error& e)
{
if(e.code() == my_errc::access_denied) //...
}
So what's the point in having std::generic_category()
at all then?
Aucun commentaire:
Enregistrer un commentaire