以下代码编译并与Visual Studio 2010一起使用,但不会在GCC下编译:
声明:
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);
执行力度:
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&gt;,boost :: _ mfi :: mf2,bool&gt;,sapphire :: transport: :ip :: TcpMimeConnection,boost :: asio :: buffers_iterator,boost :: asio :: buffers_iterator&gt;,boost :: _ bi :: list3&gt ;, boost :: arg&lt; 1&gt ;, boost :: arg&lt; 2&gt;&gt; ;&gt;&amp;)'含糊不清 [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&gt;,boost :: _ mfi :: mf2,bool&gt;,sapphire :: transport :: ip :: TcpMimeConnection,boost :: asio :: buffers_iterator,boost: :asio :: buffers_iterator&gt;,boost :: _ bi :: list3&gt;,boost :: arg&lt; 1&gt ;, boost :: arg&lt; 2&gt; &GT; &gt;,T = boost :: _ bi :: bind_t,bool&gt;,boost :: _ mfi :: mf2,bool&gt;,sapphire :: transport :: ip :: TcpMimeConnection,boost :: asio :: buffers_iterator,boost :: asio :: buffers_iterator&gt;,boost :: _ bi :: list3&gt;,boost :: arg&lt; 1&gt ;, boost :: arg&lt; 2&gt; &GT; &GT;] [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,bool&gt;,boost :: _ mfi :: mf2,bool&gt;,sapphire :: transport :: ip :: TcpMimeConnection,boost :: asio :: buffers_iterator,boost :: asio :: buffers_iterator&gt;,boost :: _ bi :: list3&gt;,boost :: arg&lt; 1&gt ;, boost :: arg&lt; 2&gt; &GT; &gt;,T = boost :: _ bi :: bind_t,bool&gt;,boost :: _ mfi :: mf2,bool&gt;,sapphire :: transport :: ip :: TcpMimeConnection,boost :: asio :: buffers_iterator,boost :: asio :: buffers_iterator&gt;,boost :: _ bi :: list3&gt;,boost :: arg&lt; 1&gt ;, boost :: arg&lt; 2&gt; &GT; &GT;] [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&gt;&amp;,boost :: asio :: basic_streambuf &gt;&amp;,boost :: _ bi :: bind_t,bool&gt;,boost :: _ mfi :: mf2,bool&gt;,sapphire :: transport :: ip :: TcpMimeConnection,boost :: asio :: buffers_iterator,boost :: asio :: buffers_iterator&gt;,boost :: _ bi :: list3&gt;,boost :: arg&lt; 1&gt ;, boost :: arg&lt; 2&gt;&gt;&gt;,boost :: asio :: detail :: wrapped_handler,boost :: _bi :: list4&gt ;, boost :: _ bi :: value,boost :: arg&lt; 1&gt;()(),boost :: arg&lt; 2&gt;()()&gt;&gt;&gt; )'
当我简单地将boost :: regex(“MIME-Version:\ s * 1.0 \ s * \ r \ n”,boost :: regex :: icase)传递给async_read_until(第三次重载)时没有问题,但我想自定义async_read_until(第四次重载)的匹配条件,当我将匹配条件设置为成员函数时遇到了问题。我需要match_version作为成员函数,因为没有办法告诉处理程序返回的原因(找到大小或匹配)。所以我知道问题在于boost :: bind(&amp; TcpMimeConnection :: match_version,shared_from_this(),_ 1,_2), 代码行,但我不知道如何解决它。
答案 0 :(得分:2)
似乎为了使用绑定器作为匹配,您需要为此类型专门化boost::asio::is_match_condition
,即使the documentation state定义result_type
的任何内容都可以使用
在添加所有必要的东西以使您的代码编译之后(下次,请发布一个可编辑的示例),我能够重现您的错误,并且我能够通过添加以下内容来修复它:
namespace boost {
namespace asio {
template <> struct is_match_condition<
decltype(
boost::bind(&TcpMimeConnection::match_version,
shared_ptr<TcpMimeConnection>(), _1, _2)
)>
: public boost::true_type {};
}
}
这显然很笨重,我会在这里使用命名的函数对象而不是绑定器。
答案 1 :(得分:0)
我看不到任何明显的东西,但asio界面非常糟糕。
当我遇到这样的问题时,我开始分解内联代码。鉴于你最后的陈述,我猜想shared_from_这可能会令人困惑。如果你开始明确地说出你所认为的所有这些内联事物的意思,你可能会发现你的错误假设。
boost::shared_ptr<TcpMimeConnection> temp = shared_from_this();
boost::bind(&TcpMimeConnection::match_version, temp, _1, _2);
或
boost::bind(&TcpMimeConnection::match_version, this, _1, _2);
答案 2 :(得分:0)
这是我根据Cubbi的答案使用的解决方案,它在visual studio 2010和gcc 4.4.2下编译:
class MatchVersion
{
public:
explicit MatchVersion(bool & versionFound) : m_versionFound(versionFound) {}
typedef boost::asio::buffers_iterator<boost::asio::streambuf::const_buffers_type> iterator;
template <typename Iterator>
std::pair<Iterator, bool> operator()(
Iterator begin, Iterator end) const
{
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)
{
m_versionFound = true;
return std::make_pair(matchResult[0].second, true);
}
else if (std::distance(begin,end) >= sapphire::transport::ip::TcpMimeConnection::MAX_STREAM_READ_SIZE)
{
return std::make_pair(end, true);
}
return std::make_pair(begin, false);
}
MatchVersion(const MatchVersion & other)
: m_versionFound(other.m_versionFound)
{
}
private:
bool& m_versionFound;
MatchVersion & operator=(const MatchVersion & other);
};
namespace boost {namespace asio {
template <> struct is_match_condition< MatchVersion >
: public boost::true_type {};
}}
namespace sapphire {namespace transport {namespace ip {
sapphire::OperationId TcpMimeConnection::read()
{
const sapphire::OperationId id = getNextOperationId();
m_versionFound = false;
aio::async_read_until(
socket(),
buffer(),
MatchVersion(m_versionFound),
m_strand.wrap(
boost::bind(
&TcpMimeConnection::handleMimeVersion,
shared_from_this(),
id,
aio::placeholders::error,
aio::placeholders::bytes_transferred)));
return id;
}
}}}