2017-08-13 46 views
1

我正在尝试使用自定义匹配函数作为boost :: asio组合操作的一部分。当传递std::move(*this)作为异步操作的处理程序时,VS2017无法推导出具有自定义匹配条件的参数。boost :: asio :: async_read_until与自定义匹配条件运算符重载混淆

组合操作是一个类,它有一个 void operator()(boost::beast::error_code ec, std::size_t bytes_transferred)过载。例如:

class match_char 
{ 
public: 
    explicit match_char(char c) : c_(c) {} 

    template <typename Iterator> 
    std::pair<Iterator, bool> operator()(
     Iterator begin, Iterator end) const 
    { 
    Iterator i = begin; 
    while (i != end) 
     if (c_ == *i++) 
     return std::make_pair(i, true); 
    return std::make_pair(i, false); 
    } 

private: 
    char c_; 
}; 

namespace asio { 
    template <> struct is_match_condition<match_char> 
    : public boost::true_type {}; 
} // namespace asio 

template<class AsyncStream, class DynamicBuffer, class Handler> 
class composed_op 
{ 
public: 
int state = 0; 
// --- boilerplate code 
void operator()(boost::beast::error_code ec, std::size_t bytes_transferred) 
{ 
    switch(state) 
    { 
      case x: 
       return boost::asio::async_read_until(stream, buffer, match_char('a'), std::move(*this)); 
    } 
} 

} 

当使用直 空隙处理机(升压::系统:: ERROR_CODE EC,标准::为size_t字节); 而不是std :: move(* this)编译得很好。以下是来自MSVC 2017的输出。任何帮助能够告诉编译器使用哪种超载将不胜感激。

1>C:\Users\xxxx\builds\dev\src\comm/read_msg.hpp(310): error C2665: 'boost::asio::read_until': none of the 5 overloads could convert all the argument types 
1>C:\Users\xxxx\builds\boost_1_64_0\boost/asio/impl/read_until.hpp(265): note: could be 'size_t boost::asio::read_until<AsyncStream,std::allocator<char>,comm::detail::match_char>(SyncReadStream &,boost::asio::basic_streambuf<std::allocator<char>> &,MatchCondition,boost::system::error_code &,void *)' 
1>  with 
1>  [ 
1>   AsyncStream=boost::beast::test::string_iostream, 
1>   SyncReadStream=boost::beast::test::string_iostream, 
1>   MatchCondition=comm::detail::match_char 
1>  ] 
1>C:\Users\xxxx\builds\boost_1_64_0\boost/asio/impl/read_until.hpp(317): note: or  'size_t boost::asio::read_until<AsyncStream,std::allocator<char>,comm::detail::match_char>(SyncReadStream &,boost::asio::basic_streambuf<std::allocator<char>> &,MatchCondition,void *)' 
1>  with 
1>  [ 
1>   AsyncStream=boost::beast::test::string_iostream, 
1>   SyncReadStream=boost::beast::test::string_iostream, 
1>   MatchCondition=comm::detail::match_char 
1>  ] 
1>C:\Users\xxxx\builds\boost_1_64_0\boost/asio/impl/read_until.hpp(206): note: or  'size_t boost::asio::read_until<AsyncStream,std::allocator<char>>(SyncReadStream &,boost::asio::basic_streambuf<std::allocator<char>> &,const boost::regex &,boost::system::error_code &)' 
1>  with 
1>  [ 
1>   AsyncStream=boost::beast::test::string_iostream, 
1>   SyncReadStream=boost::beast::test::string_iostream 
1>  ] 
1>C:\Users\xxxx\builds\boost_1_64_0\boost/asio/impl/read_until.hpp(139): note: or  'size_t boost::asio::read_until<AsyncStream,std::allocator<char>>(SyncReadStream &,boost::asio::basic_streambuf<std::allocator<char>> &,const std::string &,boost::system::error_code &)' 
1>  with 
1>  [ 
1>   AsyncStream=boost::beast::test::string_iostream, 
1>   SyncReadStream=boost::beast::test::string_iostream 
1>  ] 
1>C:\Users\xxxx\builds\boost_1_64_0\boost/asio/impl/read_until.hpp(48): note: or  'size_t boost::asio::read_until<AsyncStream,std::allocator<char>>(SyncReadStream &,boost::asio::basic_streambuf<std::allocator<char>> &,char,boost::system::error_code &)' 
1>  with 
1>  [ 
1>   AsyncStream=boost::beast::test::string_iostream, 
1>   SyncReadStream=boost::beast::test::string_iostream 
1>  ] 
1>C:\Users\xxxx\builds\dev\src\comm/read_msg.hpp(310): note: while trying to match the argument list '(boost::beast::test::string_iostream, boost::asio::streambuf, comm::detail::match_char, comm::read_msg_op<AsyncStream,DynamicBuffer,____C_A_T_C_H____T_E_S_T____74::<lambda_881e0622dc11cafb22751f624439b95e>>)' 
1>  with 
1>  [ 
1>   AsyncStream=boost::beast::test::string_iostream, 
1>   DynamicBuffer=comm::wire_msg 
1>  ] 
1>C:\Users\xxxx\builds\dev\src\comm/read_msg.hpp(286): note: while compiling class template member function 'void comm::read_msg_op<AsyncStream,DynamicBuffer,____C_A_T_C_H____T_E_S_T____74::<lambda_881e0622dc11cafb22751f624439b95e>>::operator()(boost::beast::error_code,::size_t)' 
1>  with 
1>  [ 
1>   AsyncStream=boost::beast::test::string_iostream, 
1>   DynamicBuffer=comm::wire_msg 
1>  ] 
1>C:\Users\xxxx\builds\dev\src\comm/read_msg.hpp(483): note: see reference to function template instantiation 'void comm::read_msg_op<AsyncStream,DynamicBuffer,____C_A_T_C_H____T_E_S_T____74::<lambda_881e0622dc11cafb22751f624439b95e>>::operator()(boost::beast::error_code,::size_t)' being compiled 
1>  with 
1>  [ 
1>   AsyncStream=boost::beast::test::string_iostream, 
1>   DynamicBuffer=comm::wire_msg 
1>  ] 
1>C:\Users\xxxx\builds\dev\src\comm/read_msg.hpp(483): note: see reference to class template instantiation 'comm::read_msg_op<AsyncStream,DynamicBuffer,____C_A_T_C_H____T_E_S_T____74::<lambda_881e0622dc11cafb22751f624439b95e>>' being compiled 
1>  with 
1>  [ 
1>   AsyncStream=boost::beast::test::string_iostream, 
1>   DynamicBuffer=comm::wire_msg 
1>  ] 
1>C:\Users\xxxx\builds\dev\src\comm\test\read_msg_test.cpp(55): note: see reference to function template instantiation 'void comm::read_msg<boost::beast::test::string_iostream,comm::wire_msg,____C_A_T_C_H____T_E_S_T____74::<lambda_881e0622dc11cafb22751f624439b95e>&>(AsyncStream &,DynamicBuffer &,CompletionToken)' being compiled 
1>  with 
1>  [ 
1>   AsyncStream=boost::beast::test::string_iostream, 
1>   DynamicBuffer=comm::wire_msg, 
1>   CompletionToken=____C_A_T_C_H____T_E_S_T____74::<lambda_881e0622dc11cafb22751f624439b95e> & 
1>  ] 

回答

3

我不知道你想什么,实现与std::move(*this)但即使是写得很好的处理程序,它不是,它是不是从ASIO的手之下删除的处理程序是个好主意。

不知道最终的目标,我会纠正这种情况的是这样

return boost::asio::async_read_until(
    stream, buffer, match_char('a'), 
    [this](const boost::system::error_code& ec, size_t bytes_transferred) { 
     // handler code comes here 
     // is the following what you are trying to achieve? 
     this->operator()(ec, bytes_transferred); 
    }); 

如果您关注的是composed_op<>寿命,那么你需要使用不同的方法,我会建议composed_op要继承的std :: enable_shared_from_this <>和重写这样的处理程序:

return boost::asio::async_read_until(
    stream, buffer, match_char('a'), 
    [self = shared_from_this()] 
    (const boost::system::error_code& ec, size_t bytes_transferred) { 
     // handler code comes here 
     // is the following what you are trying to achieve? 
     self->operator()(ec, bytes_transferred); 
    }); 

脚注:有关如何使用shared_ptr的额外信息,以确保在ASIO操作寿命,CHEC k out Reserving memory for asynchronous send buffers (boost asio sockets)