【发布时间】:2017-06-29 17:27:24
【问题描述】:
给定以下实现异步 future.wait() 的函数(完整示例 here):
template <typename Token, typename T>
typename boost::asio::async_result<
typename boost::asio::handler_type<Token, void()>::type
>::type
async_wait(boost::asio::io_service& ios, std::future<T>& future, Token&& token)
{
using handler_type = typename boost::asio::handler_type<Token, void()>::type;
handler_type handler(std::forward<Token>(token));
boost::asio::async_result<handler_type> result(handler);
std::async([&ios, &future, handler]() {
future.wait();
ios.dispatch([handler]() {
using boost::asio::asio_handler_invoke;
asio_handler_invoke(handler, const_cast<handler_type*>(&handler));
});
});
return result.get();
}
正确的asio_handler_invoke 仅在第二个参数是非常量时才被调用。如果 handler 是一个 lambda 捕获,它是 const 并且默认的 asio_handler_invoke 被调用。因此,要么必须使 lambdas 可变,要么需要 const_cast 才能使其正常工作。
这一切看起来都很丑陋,更重要的是对我来说也非常脆弱。所以我现在的问题是:
- 是否有更好(即更安全)的方法来实现这一点?
- 这是 asio 中的实际设计缺陷吗?应该有
const重载yield_context和朋友至少给出错误消息,而不是仅仅调用默认的asio_handler_invoke?或者这些不存在是否有正当理由? - 或者更好的是,是否应该只为默认的
asio_handler_invoke提供一个 const 重载来提供错误消息?
【问题讨论】:
-
你不能制作内部 lambda
mutable? -
是的,正如我所写的,使两个 lambdas 都可变是另一个“解决方案”。然而,这很容易出错。如果你这样做了,就没有错误,但是你的程序有一个错误,有时并不那么容易检测到。问题是这种情况是否可以通过某种方式得到改善。
标签: c++ c++11 lambda boost-asio