自定义匹配函数的 boost async_read_until 问题在 GCC 中无法编译
以下代码可在 Visual Studio 2010 中编译并使用,但无法在 GCC 下编译:
声明:
升压::asio::strand m_strand; typedef boost::asio::buffers_iterator< boost::asio::streambuf::const_buffers_type >迭代器; std::pair<迭代器,布尔> match_version(迭代器开始,迭代器结束);
实施:
std::pair<TcpMimeConnection::iterator, bool> TcpMimeConnection::match_version(iterator begin, iterator end)
{
boost::match_results<iterator> matchResult;
const bool found = boost::regex_search( begin, end, matchResult, boost::regex("MIME-Version:\\s*1.0\\s*\r\n", boost::regex::icase));
if(found)
{
versionFound = true;
return std::make_pair(matchResult[0].second, true);
}
else if (std::distance(begin,end) >= MAX_STREAM_READ_SIZE)
{
return std::make_pair(end, true);
}
return std::make_pair(begin, false);
}
/**
* Start an async read to of a mime message.
* @return the operation ID for this operation.
*/
sapphire::OperationId TcpMimeConnection::read()
{
const sapphire::OperationId id = getNextOperationId();
versionFound = false;
aio::async_read_until(
socket(),
buffer(),
boost::bind(&TcpMimeConnection::match_version, shared_from_this(), _1, _2),
m_strand.wrap(
boost::bind(
&TcpMimeConnection::handleMimeVersion,
shared_from_this(),
id,
aio::placeholders::error,
aio::placeholders::bytes_transferred)));
return id;
}
我收到以下错误:
[11:20:59]: TcpMimeConnection.cpp:372: 从这里实例化 [11:20:59]: read_until.hpp:60: 错误: 调用重载的 'helper(const boost::_bi::bind_t, bool>, boost::_mfi::mf2, bool>, sapphire::transport: :ip::TcpMimeConnection、boost::asio::buffers_iterator、boost::asio::buffers_iterator >、boost::_bi::list3 >、boost::arg<1>、boost::arg<2> > >&)' 不明确 [11:20:59]: read_until.hpp:57: 注意:候选者是: static boost::asio::detail::has_result_type::big boost::asio::detail::has_result_type::helper(U, . ..) [U = boost::_bi::bind_t, bool>, boost::_mfi::mf2, bool>,蓝宝石::transport::ip::TcpMimeConnection、boost::asio::buffers_iterator、boost::asio::buffers_iterator>、boost::_bi::list3>、boost::arg<1>、boost:: arg 2 : > >、T = boost::_bi::bind_t、bool>、boost::_mfi::mf2、bool>、蓝宝石::transport::ip::TcpMimeConnection、boost::asio::buffers_iterator、boost::asio ::buffers_iterator >、boost::_bi::list3 >、boost::arg<1>、升压::arg<2> > >] [11:20:59]: read_until.hpp:58: 注意:static char boost::asio::detail::has_result_type::helper(U, typename U::result_type*) [with U = boost::_bi: :bind_t, 布尔>, boost::_mfi::mf2, 布尔>,蓝宝石::transport::ip::TcpMimeConnection、boost::asio::buffers_iterator、boost::asio::buffers_iterator>、boost::_bi::list3>、boost::arg<1>、boost:: arg 2 : > >、T = boost::_bi::bind_t、bool>、boost::_mfi::mf2、bool>、蓝宝石::transport::ip::TcpMimeConnection、boost::asio::buffers_iterator、boost::asio ::buffers_iterator >、boost::_bi::list3 >、boost::arg<1>、升压::arg<2> > >] [11:20:59]:TcpMimeConnection.cpp:在成员函数“virtual sapphire::OperationId sapphire::transport::ip::TcpMimeConnection::read()”中: [11:20:59]: sapphire/transport/ip/TcpMimeConnection.cpp:372: 错误: 没有匹配的函数用于调用 'async_read_until(boost::asio::basic_stream_socket >&, boost::asio::basic_streambuf >&, boost::_bi::bind_t, bool>, boost::_mfi::mf2、 bool>、 sapphire::transport::ip::TcpMimeConnection、 boost::asio::buffers_iterator、 boost::asio::buffers_iterator >、 boost::_bi::list3 >、升压::arg<1>、升压::arg<2>>、 boost::asio::detail::wrapped_handler、boost::_bi::list4 >、boost::_bi::value、boost::arg<1> ()()、boost::arg<2> ; ()()> >)'
当我简单地通过了boost::regex("MIME-Version:\s*1.0\s*\r\n", boost::regex::icase) 进入 async_read_until (第三次重载)没有问题,但我想自定义匹配async_read_until (第四次重载)的条件,当我将匹配条件设为成员函数时,我遇到了问题。我需要 match_version 成为成员函数,因为无法向处理程序发出信号为什么返回(找到大小或匹配)。所以我知道问题出在 boost::bind(&TcpMimeConnection::match_version, shared_from_this(), _1, _2), 行代码,但我不知道如何修复它。
The following code compiles and works with visual studio 2010 but won't complile under GCC:
Declarations:
boost::asio::strand m_strand;
typedef boost::asio::buffers_iterator< boost::asio::streambuf::const_buffers_type > iterator;
std::pair<iterator, bool> match_version(iterator begin, iterator end);
Implimentation:
std::pair<TcpMimeConnection::iterator, bool> TcpMimeConnection::match_version(iterator begin, iterator end)
{
boost::match_results<iterator> matchResult;
const bool found = boost::regex_search( begin, end, matchResult, boost::regex("MIME-Version:\\s*1.0\\s*\r\n", boost::regex::icase));
if(found)
{
versionFound = true;
return std::make_pair(matchResult[0].second, true);
}
else if (std::distance(begin,end) >= MAX_STREAM_READ_SIZE)
{
return std::make_pair(end, true);
}
return std::make_pair(begin, false);
}
/**
* Start an async read to of a mime message.
* @return the operation ID for this operation.
*/
sapphire::OperationId TcpMimeConnection::read()
{
const sapphire::OperationId id = getNextOperationId();
versionFound = false;
aio::async_read_until(
socket(),
buffer(),
boost::bind(&TcpMimeConnection::match_version, shared_from_this(), _1, _2),
m_strand.wrap(
boost::bind(
&TcpMimeConnection::handleMimeVersion,
shared_from_this(),
id,
aio::placeholders::error,
aio::placeholders::bytes_transferred)));
return id;
}
I get the following error:
[11:20:59]: TcpMimeConnection.cpp:372: instantiated from here
[11:20:59]: read_until.hpp:60: error: call of overloaded ‘helper(const boost::_bi::bind_t, bool>, boost::_mfi::mf2, bool>, sapphire::transport::ip::TcpMimeConnection, boost::asio::buffers_iterator, boost::asio::buffers_iterator >, boost::_bi::list3 >, boost::arg<1>, boost::arg<2> > >&)’ is ambiguous
[11:20:59]: read_until.hpp:57: note: candidates are: static boost::asio::detail::has_result_type::big boost::asio::detail::has_result_type::helper(U, ...) [with U = boost::_bi::bind_t, bool>, boost::_mfi::mf2, bool>, sapphire::transport::ip::TcpMimeConnection, boost::asio::buffers_iterator, boost::asio::buffers_iterator >, boost::_bi::list3 >, boost::arg<1>, boost::arg<2> > >, T = boost::_bi::bind_t, bool>, boost::_mfi::mf2, bool>, sapphire::transport::ip::TcpMimeConnection, boost::asio::buffers_iterator, boost::asio::buffers_iterator >, boost::_bi::list3 >, boost::arg<1>, boost::arg<2> > >]
[11:20:59]: read_until.hpp:58: note: static char boost::asio::detail::has_result_type::helper(U, typename U::result_type*) [with U = boost::_bi::bind_t, bool>, boost::_mfi::mf2, bool>, sapphire::transport::ip::TcpMimeConnection, boost::asio::buffers_iterator, boost::asio::buffers_iterator >, boost::_bi::list3 >, boost::arg<1>, boost::arg<2> > >, T = boost::_bi::bind_t, bool>, boost::_mfi::mf2, bool>, sapphire::transport::ip::TcpMimeConnection, boost::asio::buffers_iterator, boost::asio::buffers_iterator >, boost::_bi::list3 >, boost::arg<1>, boost::arg<2> > >]
[11:20:59]: TcpMimeConnection.cpp: In member function ‘virtual sapphire::OperationId sapphire::transport::ip::TcpMimeConnection::read()’:
[11:20:59]: sapphire/transport/ip/TcpMimeConnection.cpp:372: error: no matching function for call to ‘async_read_until(boost::asio::basic_stream_socket >&, boost::asio::basic_streambuf >&, boost::_bi::bind_t, bool>, boost::_mfi::mf2, bool>, sapphire::transport::ip::TcpMimeConnection, boost::asio::buffers_iterator, boost::asio::buffers_iterator >, boost::_bi::list3 >, boost::arg<1>, boost::arg<2> > >, boost::asio::detail::wrapped_handler, boost::_bi::list4 >, boost::_bi::value, boost::arg<1> ()(), boost::arg<2> ()()> > >)’
When I simply passed the boost::regex("MIME-Version:\s*1.0\s*\r\n", boost::regex::icase) into the async_read_until (third overload) there was no problems, but I wanted to customize the match condition of the async_read_until (fourth overload) and I ran into problems when I made the match condition an member function. I need match_version to be a member function since there is no way to signal the handler why its returning (size or match found). So I know the problem is with the boost::bind(&TcpMimeConnection::match_version, shared_from_this(), _1, _2),
line of code but I don't know how to fix it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看来,为了使用活页夹作为匹配,您需要专门针对这种类型的
boost::asio::is_match_condition
,即使 文档声明任何定义可以使用result_type
。添加所有必要的内容以使代码编译(下次,请发布可编译的示例)后,我能够重现您的错误,并且我能够通过添加以下内容来修复它:
这显然很笨拙,我会使用这里是一个命名函数对象而不是绑定器。
It appears that in order to use a binder as a match, you will need to specialize
boost::asio::is_match_condition
for this type, even though the documentation states that anything that defines aresult_type
can be used.After adding all the necessary stuff to make your code compile (next time, please post a compilable example), I was able to reproduce your error, and I was able to fix it by adding the following:
This is obviously unwieldy, I would use a named function object here instead of a binder.
这是我根据 Cubbi 的答案使用的解决方案,该解决方案在 Visual Studio 2010 和 gcc 4.4.2 下编译:
Here is the solution I used based off of Cubbi's answer that compiles under both visual studio 2010 and gcc 4.4.2:
我看不到任何明显的东西,但 asio 接口很糟糕。
当我遇到这样的问题时,我开始分解内联代码。鉴于您最后的陈述,我猜想 shared_from_this 可能会令人困惑。如果您开始明确说出您认为所有这些内联事物的含义,您可能会发现自己的错误假设。
或者
I can't see anything obvious, but asio interfaces are abysmal.
When I have problems like this, I start breaking up inline code. Given your last statement, I'd guess shared_from_this may be confusing it. If you start explicitly saying what you think all these inline things mean, you may discover your bad assumption.
or