比较boost :: system :: error_category

时间:2017-03-23 17:45:09

标签: c++ boost-asio boost-system

对于输出" asio.misc"的错误,以下比较失败。 for errorCode.category()。name()和" end of file" for errorCode.message()

如果它声称属于asio.misc类别,那么为什么(errorCode.category()== boost :: asio :: error :: misc_category)的if条件评估为false?

谷歌搜索(包括这里的答案)说,一个boost :: system :: error_code可以在多个类别中具有相同的值,所以我假设为了获得正确的消息和意义我们必须比较boost :: system :: error_category以及boost :: system :: error_code :: value。

如果无法正常工作,我们如何正确比较该类别?

有问题的代码:

//--------------------------------------------------------------------------------------------------
std::string ClientSocketASIO::ErrorCodeToString(const boost::system::error_code & errorCode)
{
    std::ostringstream debugMsg;
    debugMsg << " Error Category: " << errorCode.category().name() << ". "
             << " Error Message: "  << errorCode.message() << ". ";

    if( errorCode.category() == boost::asio::error::misc_category )
    {
        switch (errorCode.value())
        {
        case boost::asio::error::eof:
            debugMsg << ". Server has disconnected.";
            break;
        case boost::asio::error::connection_refused:
            debugMsg << ". Connection Refused";
            break;
        default:
            debugMsg << ". Unknown Error.";
            break;
        }
    }
    else
    {
        debugMsg << ". Unknown Error category.";
    }

    return debugMsg.str();
}

编辑:

根据https://theboostcpplibraries.com/boost.systemBoost::file_system: Checking error codes

人们通常会错误地编写代码,只比较错误值而不是类别。仅错误值不是唯一的,可能出现在多个类别中。用户还可以自由创建自己的错误代码和类别。因此,两者都必须进行比较。我认为这不会对大量应用程序产生影响,因为他们只使用一个功能或库来提升他们的项目和/或大多数错误代码被映射到Windows错误代码,这是最好的努力不要碰撞。

由于我的工作几乎阻止了所有事情,因此我必须使用另一台计算机来获取提升邮件列表。

http://boost.2283326.n4.nabble.com/Compare-boost-system-error-category-td4692861.html#a4692869

根据那里的一个家伙,比较失败的原因是因为boost库是静态链接的,并且boost :: system :: error_category :: operator ==比较地址,所以LHS是一个lib中的地址而RHS是另一个地址。当它们被预期时,它们不会是平等的。

使用运营商的地址==对我来说似乎是一个非常愚蠢的举动。如果发现任何新知识,我会继续在boost邮件列表上咆哮并在这里为其他人编辑。

目前,我是动态链接和使用表单

//--------------------------------------------------------------------------------------------------
std::string ClientSocketASIO::ErrorCodeToString(const boost::system::error_code & errorCode)
{
    std::ostringstream debugMsg;
    debugMsg << " Error Category: " << errorCode.category().name() << ". "
             << " Error Message: "  << errorCode.message() << ". ";

    // IMPORTANT - These comparisons only work if you dynamically link boost libraries
    //             Because boost chose to implement boost::system::error_category::operator == by comparing addresses
    //             The addresses are different in one library and the other when statically linking.
    //
    // We use make_error_code macro to make the correct category as well as error code value.
    // Error code value is not unique and can be duplicated in more than one category.
    if (errorCode == make_error_code(boost::asio::error::connection_refused))
    {
        debugMsg << ". Connection Refused";
    }
    else if (errorCode == make_error_code(boost::asio::error::eof))
    {
        debugMsg << ". Server has disconnected.";
    }
    else
    {
        debugMsg << ". boost::system::error_code has not been mapped to a meaningful message.";
    }

    return debugMsg.str();
}

然而,当我静态链接到提升时,这不起作用。如果有人对我们如何正确比较boost :: system :: error_code并获得预期结果有任何建议,请让我们深入了解。

1 个答案:

答案 0 :(得分:1)

C ++ 11标准意味着每个错误类别实例都应具有 全球唯一的地址和平等的比较应使用它 要比较的地址。不幸的是,这在便携式设备中并不可靠 代码,只有Dinkumware STL实现真正的地址唯一性 在过程中的任何地方,它都会增加一个完整的内存屏障来实现 即它很贵。

Boost的实现质量与libstdc ++或libc ++相同, 你可以在某些情况下获得多个实例 可以有不同的地址。

在我自己的代码中,我先做比较运算符,如果失败了我 做一个类别名称()的strcmp()。到目前为止,这并没有让我感到困惑。 我个人认为错误类别的这一方面是一个 标准中的缺陷,如指定的那样强制非标题 实现,如果你想要它符合,甚至没有 覆盖RTLD_LOCAL,这意味着您需要回退到命名共享 记忆或一些黑客。