【问题标题】:boost::deadline_timer error: static assertion failed: WaitHandler type requirements not metboost::deadline_timer 错误:静态断言失败:未满足 WaitHandler 类型要求
【发布时间】:2021-11-18 14:52:43
【问题描述】:

我有一个代表套接字的cnx 类,它还必须有一个计时器,如果客户端停留超过cnx::timeout_mili 毫秒而没有响应,那么我将关闭连接。每个计时器将在建立连接时启动,或者在实例化 cnx 对象时启动。套接字部分工作正常,现在当我尝试将计时器添加到 cnx 类时,它的构建失败并出现以下错误:

In file included from /home/pcuser/src/boost_1_71_0/boost/asio/impl/execution_context.hpp:18,
                 from /home/pcuser/src/boost_1_71_0/boost/asio/execution_context.hpp:409,
                 from /home/pcuser/src/boost_1_71_0/boost/asio/detail/scheduler.hpp:21,
                 from /home/pcuser/src/boost_1_71_0/boost/asio/system_context.hpp:19,
                 from /home/pcuser/src/boost_1_71_0/boost/asio/impl/system_executor.hpp:22,
                 from /home/pcuser/src/boost_1_71_0/boost/asio/system_executor.hpp:129,
                 from /home/pcuser/src/boost_1_71_0/boost/asio/associated_executor.hpp:21,
                 from /home/pcuser/src/boost_1_71_0/boost/asio.hpp:21,
                 from /home/pcuser/src/cpp-server/comum.h:9,
                 from /home/pcuser/src/cpp-server/cnx.h:4,
                 from /home/pcuser/src/cpp-server/cnx.cpp:1:
/home/pcuser/src/boost_1_71_0/boost/asio/basic_deadline_timer.hpp: In instantiation of ‘void boost::asio::basic_deadline_timer<Time, TimeTraits, Executor>::initiate_async_wait::operator()(WaitHandler&&, boost::asio::basic_deadline_timer<Time, TimeTraits, Executor>*) const [with WaitHandler = void (cnx::*)(const boost::system::error_code&); Time = boost::posix_time::ptime; TimeTraits = boost::asio::time_traits<boost::posix_time::ptime>; Executor = boost::asio::executor]’:
/home/pcuser/src/boost_1_71_0/boost/asio/async_result.hpp:82:49:   required from ‘static boost::asio::async_result<CompletionToken, Signature>::return_type boost::asio::async_result<CompletionToken, Signature>::initiate(Initiation&&, RawCompletionToken&&, Args&& ...) [with Initiation = boost::asio::basic_deadline_timer<boost::posix_time::ptime>::initiate_async_wait; RawCompletionToken = void (cnx::*)(const boost::system::error_code&); Args = {boost::asio::basic_deadline_timer<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::executor>*}; CompletionToken = void (cnx::*)(const boost::system::error_code&); Signature = void(boost::system::error_code); boost::asio::async_result<CompletionToken, Signature>::return_type = void]’
/home/pcuser/src/boost_1_71_0/boost/asio/async_result.hpp:257:25:   required from ‘typename std::enable_if<boost::asio::detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, typename boost::asio::async_result<typename std::decay<_Tp>::type, Signature>::return_type>::type boost::asio::async_initiate(Initiation&&, CompletionToken&, Args&& ...) [with CompletionToken = void (cnx::*)(const boost::system::error_code&); Signature = void(boost::system::error_code); Initiation = boost::asio::basic_deadline_timer<boost::posix_time::ptime>::initiate_async_wait; Args = {boost::asio::basic_deadline_timer<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::executor>*}; typename std::enable_if<boost::asio::detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, typename boost::asio::async_result<typename std::decay<_Tp>::type, Signature>::return_type>::type = void; typename boost::asio::async_result<typename std::decay<_Tp>::type, Signature>::return_type = void; typename std::decay<_Tp>::type = void (cnx::*)(const boost::system::error_code&)]’
/home/pcuser/src/boost_1_71_0/boost/asio/basic_deadline_timer.hpp:629:73:   required from ‘typename boost::asio::async_result<typename std::decay<_Functor>::type, void(boost::system::error_code)>::return_type boost::asio::basic_deadline_timer<Time, TimeTraits, Executor>::async_wait(WaitHandler&&) [with WaitHandler = void (cnx::*)(const boost::system::error_code&); Time = boost::posix_time::ptime; TimeTraits = boost::asio::time_traits<boost::posix_time::ptime>; Executor = boost::asio::executor; typename boost::asio::async_result<typename std::decay<_Functor>::type, void(boost::system::error_code)>::return_type = void; typename std::decay<_Functor>::type = void (cnx::*)(const boost::system::error_code&)]’
/home/pcuser/src/cpp-server/cnx.cpp:15:25:   required from here
/home/pcuser/src/boost_1_71_0/boost/asio/detail/handler_type_requirements.hpp:376:62: error: static assertion failed: WaitHandler type requirements not met
  373 |       sizeof(boost::asio::detail::one_arg_handler_test( \
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     
  374 |           boost::asio::detail::rvref< \
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                       
  375 |             asio_true_handler_type>(), \
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~                      
  376 |           static_cast<const boost::system::error_code*>(0))) == 1, \
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
/home/pcuser/src/boost_1_71_0/boost/asio/detail/handler_type_requirements.hpp:105:20: note: in definition of macro ‘BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT’
  105 |      static_assert(expr, msg);
      |                    ^~~~
/home/pcuser/src/boost_1_71_0/boost/asio/basic_deadline_timer.hpp:647:7: note: in expansion of macro ‘BOOST_ASIO_WAIT_HANDLER_CHECK’
  647 |       BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/pcuser/src/boost_1_71_0/boost/asio/detail/handler_type_requirements.hpp:376:62: note: ‘(sizeof (boost::asio::detail::one_arg_handler_test<void (cnx::*)(const boost::system::error_code&)>(boost::asio::detail::rvref<void (cnx::*)(const boost::system::error_code&)>(), 0)) == 1)’ evaluates to false
  373 |       sizeof(boost::asio::detail::one_arg_handler_test( \
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     
  374 |           boost::asio::detail::rvref< \
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                       
  375 |             asio_true_handler_type>(), \
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~                      
  376 |           static_cast<const boost::system::error_code*>(0))) == 1, \
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
/home/pcuser/src/boost_1_71_0/boost/asio/detail/handler_type_requirements.hpp:105:20: note: in definition of macro ‘BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT’
  105 |      static_assert(expr, msg);
      |                    ^~~~
/home/pcuser/src/boost_1_71_0/boost/asio/basic_deadline_timer.hpp:647:7: note: in expansion of macro ‘BOOST_ASIO_WAIT_HANDLER_CHECK’
  647 |       BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/pcuser/src/boost_1_71_0/boost/asio/detail/handler_type_requirements.hpp:280:36: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘boost::asio::detail::lvref<void (cnx::*)(const boost::system::error_code&)>() (...)’, e.g. ‘(... ->* boost::asio::detail::lvref<void (cnx::*)(const boost::system::error_code&)>()) (...)’
  279 |         boost::asio::detail::lvref< \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  280 |           asio_true_handler_type>()( \
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
  281 |             boost::asio::detail::lvref<const boost::system::error_code>()), \
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/pcuser/src/boost_1_71_0/boost/asio/basic_socket.hpp:1817:7: note: in expansion of macro ‘BOOST_ASIO_CONNECT_HANDLER_CHECK’
 1817 |       BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/Server.dir/build.make:90: CMakeFiles/Server.dir/cnx.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....


make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/Server.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

我的代码如下:

cnx.h

#ifndef CNX_H
#define CNX_H

#include <boost/asio.hpp>
using boost::asio::ip::tcp;

typedef boost::asio::io_service ioservice;

using namespace std;
class cnx
{
public:
    inline static int timeout_mili = 10000;
    cnx(ioservice& io);
    void timer_counter_reset();
    bool conectado;

private:
    tcp::socket s;
    boost::asio::io_service timer_io;
    boost::asio::deadline_timer cnx_timer;

    void timer_ended(const boost::system::error_code& e);
};

#endif // CNX_H

cnx.cpp

#include "cnx.h"

cnx::cnx(ioservice& io) :
    s(tcp::socket(io)),
    conectado(false),
    cnx_timer(boost::asio::deadline_timer(timer_io, boost::posix_time::milliseconds(cnx::timeout_mili)))
{
    timer_io.run();

    cnx_timer.async_wait(&cnx::timer_ended);
}

// I'll call this outsite so the timer gets reset and restart couting
void cnx::timer_counter_reset()
{
    cnx_timer.cancel();
    cnx_timer.async_wait(&cnx::timer_ended);
}

void cnx::timer_ended(const boost::system::error_code& e)
{
    if(e){
        cout << "cnx id " << id << " resetted timer" << endl;
        return;
    }
    this->conectado = false;
}

我不知道我在函数签名上做错了什么。我的问题似乎还没有得到回答here。提前致谢。

编辑 所以,问题似乎是在 async_wait 调用中引用方法 &amp;cnx::timer_ended 时,我在 cnx.h 中添加了一个测试函数,如下所示:

inline static void testtt(const boost::system::error_code& e)
{
    cout << "testtt" << endl;
    return;
}

并将 async_await 调用从 cnx_timer.async_wait(&amp;cnx::timer_ended);cnx_timer.async_wait(cnx::testtt);

它奏效了。但是我仍然不知道如何解决它,因为我需要更改 cnx 对象的每个实例的值,所以我不能使用静态函数......有什么想法吗?

编辑 2 即使现在正在编译,代码也没有按预期工作,函数“testtt”根本没有被触发。

【问题讨论】:

    标签: c++ boost c++17 boost-asio asio


    【解决方案1】:

    这是绑定成员函数的经典“问题”。对于成员函数,您还需要有一个“this 值”,它来自哪里?

    大致有两种方法:

    • 绑定
    • λ

    绑定

    使用例如boost::bind你可以

    cnx_timer.async_wait(boost::bind(&cnx::timer_ended, this,
                                     boost::asio::placeholders::error()));
    

    现在回调绑定到this。请记住,您必须确保 cnx 对象保持有效。还要注意线程安全。

    旁注;

    // I'll call this outsite so the timer gets reset and restart couting
    void cnx::timer_counter_reset()
    {
        cnx_timer.cancel();
    

    这不会重置计时器。它只是取消任何挂起的异步等待。要真正重置它,请再次使用expires_from_nowexpires_at

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-01
      相关资源
      最近更新 更多