std :: generic_category()没用?

时间:2015-01-03 23:03:15

标签: c++ c++11

来自C ++ 11标准的引用:

  

19.5.1.5错误类别对象[syserr.errcat.objects]

 const error_category& system_category() noexcept;
     

4 备注:对象的equivalent虚函数应表现为   为类error_category指定。对象的name虚拟   function应返回指向字符串"system"的指针。对象的   default_error_condition虚函数的行为如下:

     

如果参数ev对应于POSIX errnoposv,则为   函数应返回error_condition(posv, generic_category())。   否则,该函数将返回error_condition(ev, system_category())。   什么构成任何给定的通信   操作系统未指定。 [注意:潜在的数量   系统错误代码很大且无界限,有些可能不对应   到任何POSIX errno值。因此,实现被给予纬度   确定对应关系 - 结束记录]

换句话说,某些操作系统下面的代码可能无效,因为system_category().default_error_condition()没有正确映射到generic_category()条件(标准完全允许):

try
{
    // do some file IO
}
catch(const std::system_error& e)
{
    if(e.code() == std::errc::permission_denied) //...
}

唯一的解决方案是为generic_category()实现自己的自定义替换,并为您需要的所有操作系统代码(对于您需要的所有操作系统)进行映射。

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 // ...
    }
// ...

然后使用您自己的类别而不是generic_category

catch(const std::system_error& e)
{
    if(e.code() == my_errc::access_denied) //...
}

那么在std::generic_category()之后的重点是什么呢?

1 个答案:

答案 0 :(得分:0)

应该问一个问题:您是否正在尝试编写绝对肯定不是编译器特定的代码,或者您是否可以编写一些代码知道它需要某些特定的编译器或编译器系列?

标准是告诉你如何做前者。

虽然编写代码来处理所有编译器是一个很好的经验法则(至少在那些符合标准的编译器上),但有时这意味着你将重新实现已经实现的一些东西。特定编译器/库的实现。