我正在编写一个使用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_code
和std::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
的错误代码。
答案 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 answer从boost::system::error_code
转换为std::error_code
(另请参阅此相关question)。< / p>
更简单的方法是让remoteProcedureCall
获取指向error_code
的可选指针。这避免了重复的功能:一个设置错误代码,另一个抛出异常。
答案 1 :(得分:1)
这应该有效,假设ec
是boost::system_error::error_code
std::make_error_code( static_cast<std::errc::errc>(ec.value()) );
我认为boost::system::errc::errc_t
枚举广告已映射到std::errc
中的相同值。