gpt4 book ai didi

c++ - 绑定(bind) boost::asio::steady_timer::async_wait

转载 作者:搜寻专家 更新时间:2023-10-31 00:59:24 27 4
gpt4 key购买 nike

我想转这个电话:

timer.async_wait(handler);

进入这个电话:

func(handler);

所以我尝试使用 std::bind:

#include <functional>

#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/system/error_code.hpp>

using std::bind;
using std::function;

using boost::asio::io_service;
using boost::asio::steady_timer;
using boost::system::error_code;

int main(int, char**) {
using namespace std::placeholders;

io_service io_s;
steady_timer timer (io_s);

// error
function<void(function<void(const error_code&)>)> bound =
bind(&steady_timer::async_wait, timer, _1);

return 0;
}

但它不会编译!像这样编译时:

g++-4.9 -std=c++11 -Wall -I/usr/local/include -L/usr/local/lib -lboost_system -o bin main.cpp

错误信息是这样的:

main.cpp:22:46: error: no matching function for call to 'bind(<unresolved overloaded function type>, boost::asio::steady_timer&, const std::_Placeholder<1>&)'
bind(&steady_timer::async_wait, timer, _1);

我尝试了各种方法(例如转换、模板参数、函数对象),但就是无法编译。

我正在使用 Boost ASIO 1.58 和 the documentation说如下:

template<
typename WaitHandler>
void-or-deduced async_wait(
WaitHandler handler);

here你可以看到 WaitHandler 是什么。我不明白 void-or-deduced 是什么意思,但我想这可能是什么让我遇到了困难?我已经盯着这个问题看了很长时间,以至于我认为我已经有了狭隘的视野。

在这种情况下如何正确使用 std::bind

最佳答案

从启动函数 (async_*) 返回的对象类型依赖于提供给启动函数的处理程序类型。文档用其 void-or-deduced 指示此变体类型。

尝试使用 functionbind这里会有多个问题:

  • timer.async_wait() 的函数签名如果不首先指定将提供的确切处理程序类型以便可以推导出返回类型,则无法解析
  • 将处理程序类型更改为 std::function<...>可能会产生意想不到的后果,因为默认 asio_handler_*将调用 Hook 而不是自定义 Hook 。参见 this回答有关处理程序 Hook 的更多详细信息。

相反,考虑使用自定义仿函数来完成绑定(bind),同时允许处理程序类型正确传递给 Asio:

/// @brief Custom functor used to initiate async_wait operations.
template <typename Timer>
class async_wait_functor
{
public:
async_wait_functor(Timer& timer): timer_(timer) {}

template <typename WaitHandler>
auto operator()(WaitHandler handler)
{
return timer_.async_wait(handler);
}

private:
Timer& timer_;
};

/// @brief Auxiliary factory function for binding a timer.
template <typename Timer>
async_wait_functor<Timer> bind_async_wait(Timer& timer)
{
return async_wait_functor<Timer>(timer);
}

...

auto func = bind_async_wait(timer);
func(handler);

这是一个完整的例子demonstrating使用自定义仿函数:

#include <iostream>
#include <functional>
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>

/// @brief Custom functor used to initiate async_wait operations.
template <typename Timer>
class async_wait_functor
{
public:
async_wait_functor(Timer& timer): timer_(timer) {}

template <typename WaitHandler>
auto operator()(WaitHandler handler)
{
return timer_.async_wait(handler);
}

private:
Timer& timer_;
};

/// @brief Auxiliary factory function for binding a timer.
template <typename Timer>
async_wait_functor<Timer> bind_async_wait(Timer& timer)
{
return async_wait_functor<Timer>(timer);
}

int main()
{
boost::asio::io_service io_service;
boost::asio::steady_timer timer(io_service);
auto handler = [](const boost::system::error_code&) {
std::cout << "in handler" << std::endl;
};

auto func = bind_async_wait(timer);
func(handler);

timer.cancel();
io_service.run();
}

运行时输出:

in handler

documentation详细说明如何确定返回类型:

By default, initiating functions return void. This is always the case when the handler is a function pointer, C++11 lambda, or a function object produced by boost::bind or std::bind.

For other types, the return type may be customised via [...] a specialisation of the async_result template, which is used both to determine the return type and to extract the return value from the handler.

例如,Boost.Asio 专攻 boost::asio::async_result对于 boost::asio::use_future .当boost::asio::use_future作为初始函数的处理程序提供,返回类型为 std::future .

关于c++ - 绑定(bind) boost::asio::steady_timer::async_wait,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33371880/

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