boost :: asio :: yield_context可以设置一个std :: error_code而不是boost :: system :: error_code吗?

时间:2015-01-15 20:57:34

标签: c++ c++11 boost boost-asio coroutine

我正在编写一个使用Boost.Asio的C ++ 11网络库。我想公开一个API,允许用户使用堆栈协程。

boost::asio::yield_context重载[]运算符,以便异步操作可以设置错误代码而不是抛出异常。例如:

std::size_t n = my_socket.async_read_some(buffer, yield[ec]);
if (ec)
{
    // An error occurred.
}

我的图书馆使用std::error_codestd::system_error来报告错误。我的问题是如何让boost::asio::yield_context设置std::error_code而不是boost::system::error_code?我希望我的图书馆用户能够做到这一点:

std::error_code ec;
auto result = remoteProdedureCall(args, yield[ec]);
if (ec)
    handleError();

其中remoteProcedureCall类似于:

Result remoteProcedureCall(Args args, boost::asio::yield_context yield)
{
    //...
    boost::asio::async_write(socket_, argsBuffer, yield);
    boost::asio::async_read(socket_, resultBuffer, yield);
    if (invalidResult())
        // Return a std::error_code via the yield object somehow???
        // (My error codes belong to a custom error_category)
    // ...
    return result;
}

P.S。我应该指出我的图书馆使用属于自定义error_category的错误代码。

2 个答案:

答案 0 :(得分:2)

我最终做了一些比试图强迫yield_context设置std::error_code更简单的事情:

// This overload sets a std::error_code if there's an error.
Result remoteProcedureCall(Args args, boost::asio::yield_context yield,
                           std::error_code& userErrorCode)
{
    //...
    boost::system::error_code ec;
    boost::async_write(socket_, buffer, yield[ec];
    if (ec)
    {
        userErrorCode = toStdErrorCode(ec);
        return Result();
    }
    // ...
    if (someNonBoostError)
    {
        userErrorCode = make_error_code(myCustomErrorCode);
        return Result();
    }
    // ...
    return result;
}

// This overload throws an exception if there's an error
Result remoteProcedureCall(Args args, boost::asio::yield_context yield)
{
    std::error_code ec;
    auto result = remoteProcedureCall(args, yield, ec);
    if (ec)
        throw std::system_error(ec);
    return result;
}

其中toStdErrorCode根据Sam answerboost::system::error_code转换为std::error_code(另请参阅此相关question)。< / p>


更简单的方法是让remoteProcedureCall获取指向error_code的可选指针。这避免了重复的功能:一个设置错误代码,另一个抛出异常。

答案 1 :(得分:1)

这应该有效,假设ecboost::system_error::error_code

std::make_error_code( static_cast<std::errc::errc>(ec.value()) );

我认为boost::system::errc::errc_t枚举广告已映射到std::errc中的相同值。