我正在尝试使用自定义匹配函数作为boost :: asio组合操作的一部分。传入std::move(*this)
作为异步操作的处理程序时,VS2017无法使用自定义匹配条件推导出参数。
组合操作是一个具有的类
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));
}
}
}
使用笔直时 void handler(boost :: system :: error_code ec,std :: size_t bytes); 而不是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> ]
答案 0 :(得分: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&lt;&gt;并重写这样的处理程序:
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)