函数签名以boost :: bind作为参数(boost :: asio timer callback)?

时间:2015-03-12 17:08:32

标签: c++ boost boost-asio

我试图编写一个包装器方法set_timer(),它需要一个时间和回调(用boost :: bind表示)并设置deadline_timer来运行该回调。

目前回调非常简单:

void foo::callback(const boost::system::error_code& error) {
    std::cout << "callback" << std::endl;
}

对于set_timer()我有:

void foo::set_timer(boost::posix_time::ptime time,
                    boost::function<void(const boost::system::error_code&)> handler) {
    pimpl->t.expires_at(time);
    pimpl->t.async_wait(handler);
}

我现在试图从foo对象中调用它:

set_timer(boost::posix_time::seconds(1), boost::bind (&foo::callback, this));

编译时出现错误信息:

foo.cpp: In member function ‘void foo::run()’:
foo.cpp:50: error: no matching function for call to ‘foo::set_timer(boost::posix_time::seconds, boost::_bi::bind_t<void (&)(const boost::system::error_code&), boost::_mfi::dm<void(const boost::system::error_code&), foo>, boost::_bi::list1<boost::_bi::value<foo*> > >)’
src/foo_sdr.cpp:43: note: candidates are: void foo::set_timer(boost::posix_time::ptime, boost::function<void(const boost::system::error_code&)>)

看起来签名要比我想象的要复杂得多或简单得多。

我想用以下内容替换回调签名:

typedef std::function<void(const boost::system::error_code&)> timer_callback_t;

我在CentOS 6.6上使用gcc 4.4.7和-std = gnu ++ 0x,因此无法访问auto

How do you pass boost::bind objects to a function?What is the return type of boost::bind?没有运气,我不明白我的情况会有什么不同。

1 个答案:

答案 0 :(得分:3)

确实boost::bind的返回类型是表达式模板,比函数类型复杂得多。毕竟,它不是一个函数,而是一个函数 object (带有绑定属性值)的动态合成类型。

这种类型是实现定义的,只要您确保生成的签名与您尝试分配给的签名一致,您就不需要知道。实际上,处理程序需要类型为error_code的单个未绑定参数,因此请按照注释中的建议添加占位符:

boost::bind (&foo::callback, this, ai::placeholders::error)

一些常规修复,以及使其自包含的更多步骤:

  • time_duration无法转换为ptime。也许你想说expires_from_now而不是expires_at。但如果您确实需要后者,请指定绝对截止日期:

    posix_time::microsec_clock::universal_time() + posix_time::seconds(1)
    

<强> Live On Coliru

#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>

namespace ai = boost::asio;

struct foo {

    ai::io_service svc;
    ai::deadline_timer t{svc};

    void callback(const boost::system::error_code& error) {
        std::cout << "callback: " << error.message() << std::endl;
    }

    void set_timer(boost::posix_time::ptime time, boost::function<void(const boost::system::error_code&)> handler) {
        t.expires_at(time);
        t.async_wait(handler);
    }

    void fornow() {
        set_timer(
                boost::posix_time::microsec_clock::universal_time() + boost::posix_time::seconds(1),
                boost::bind (&foo::callback, this, ai::placeholders::error)
            );

        svc.run();
    }
};

int main() {
    foo o;
    o.fornow();
}

1秒后打印:

callback: Success