boost::asio::async_read_until 与自定义匹配条件运算符重载混淆
Posted
技术标签:
【中文标题】boost::asio::async_read_until 与自定义匹配条件运算符重载混淆【英文标题】:boost::asio::async_read_until with custom match condition operator overload confusion 【发布时间】:2018-01-21 15:34:25 【问题描述】:我正在尝试使用自定义匹配函数作为 boost::asio 组合操作的一部分。 VS2017 在传入 std::move(*this)
作为异步操作的处理程序时,无法推断具有自定义匹配条件的参数。
组合操作是一个具有
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));
使用直线时 无效处理程序(boost::system::error_code ec,std::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> ]
【问题讨论】:
【参考方案1】:我不确定你想用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 操作的生命周期的更多信息,请查看Reserving memory for asynchronous send buffers (boost asio sockets)
【讨论】:
以上是关于boost::asio::async_read_until 与自定义匹配条件运算符重载混淆的主要内容,如果未能解决你的问题,请参考以下文章