gpt4 book ai didi

c++ - asio_handler_invoke 常量重载

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:44:21 24 4
gpt4 key购买 nike

给定以下实现异步 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。因此,要么必须使 lambda 可变,要么需要 const_cast 才能正常工作。

这一切看起来都很丑陋,更重要的是,对我来说也非常脆弱。所以我现在的问题是:

  • 是否有更好(即更安全)的方法来实现这一点?
  • 这是 asio 中的实际设计缺陷吗?yield_context 和 friend 应该有 const 重载,至少给出一条错误消息,而不是仅仅调用默认的 asio_handler_invoke?还是这些不存在的正当理由?
  • 或者更好的是,是否应该只为给出错误消息的默认 asio_handler_invoke 设置一个 const 重载?

最佳答案

非常有趣的问题。

首先,前提看起来很奇怪。 asio_handler_invoke 用于在与某些给定处理程序 相同的执行上下文中调用另一个处理程序(您无法了解其详细信息,因为它可能包含在某些(用户定义的)类型中)。

所以我认为有

F f;
using boost::asio::asio_handler_invoke;
asio_handler_invoke(f, &f);

在概念上不添加任何东西,并且可能会降低性能(例如,通过 strand-wrapping 两次)。

它也很容易导致不良结果。想象一下 F 是 Tanner 的样本计数包装器的包装器,它只会导致重复计算调用。

分析问题

所以剩下的问题是处理程序调用是否对内置处理程序包装类型做了正确的事情,让我们使用 Tanner 的计数包装器,我们确实看到了

{
operation_counter oc;

auto handler = oc.wrap([](boost::system::error_code ec) {
std::cout << "Inner (" << ec.message() << ")\n";
});

asio_handler_invoke([]() {
std::cout << "Outer\n";
}, &handler);

std::cout << "mutable: " << oc.count() << "\n";
}

打印

Outer
mutable: 1

但是更改为 auto const handler 打印:

Outer
const: 0

查看两种情况 Live On Coliru

确实,在数量上增加了一个过载

  template <typename Function>
friend void asio_handler_invoke(Function function, counting_handler const *context);

消除差异:

Live On Coliru

所以奇怪的不是重载不适用于 const 处理程序上下文,而是遗漏回落到默认行为的事实悄无声息且没有警告 .

事实上,我建议向库开发人员报告这一点,因为我可以看到对于诸如 boost::asio::strand 之类的事情,这会悄悄地出错,这将导致可预测的问题。

关于c++ - asio_handler_invoke 常量重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42175066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com