gpt4 book ai didi

c++ - boost::asio::async_read_until 与自定义匹配条件运算符重载混淆

转载 作者:行者123 更新时间:2023-11-30 02:23:51 33 4
gpt4 key购买 nike

我正在尝试使用自定义匹配函数作为 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> ]

最佳答案

我不确定你想用 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)

关于c++ - boost::asio::async_read_until 与自定义匹配条件运算符重载混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45663619/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com