我正在使用boost :: bind将处理函数传递给boost :: asio :: async_write。当我使用自由函数时,它工作正常,但是当我尝试在类中移动函数时,bind会产生我无法解密的错误。
我写了一些数据:
boost::asio::async_write(*socket,
boost::asio::buffer(data(),
length()),
boost::bind(handlermessagewrite,
boost::asio::placeholders::error,
this,
boost::asio::placeholders::bytes_transferred));
然后我用一个签名为的自由函数处理写:
void handlermessagewrite(const boost::system::error_code& errorcode,
iodata *msg,
size_t bytes_transferred);
这一切都按预期工作。
我在类ioclient
中移动处理程序:
class ioclient {
public:
void handlermessagewrite(const boost::system::error_code& errorcode,
iodata *msg,
size_t bytes_transferred);
}
void ioclient::handlermessagewrite(const boost::system::error_code& errorcode,
iodata *msg,
size_t bytes_transferred);
并相应地调整boost :: bind代码,如官方asio教程中所示:
- boost::bind(handlermessagewrite,
+ boost::bind(&ioclient::handlermessagewrite,
但是,这会产生一些非常不透明的编译错误,但是其中一条线似乎最终在我的IDE(code :: blocks)中被截断的事实没有帮助:
\升压\绑定\ bind_template.hpp | 102 |需要来自'boost :: _ bi :: bind_t :: result_type boost :: _ bi :: bind_t :: operator()(const A1&,const A2&)[with A1 = boost :: system :: error_code; A2 = unsigned int; R =无效; F = boost :: _ mfi :: mf2; L = boost :: _ bi :: list3(*)(),boost :: _ bi :: value,boost :: arg< 2> (*)()取代; boost :: _ bi :: bind_t :: result_type = void]'| \提升\ ASIO \ IMPL \ write.hpp | 261 |需要来自'void boost :: asio :: detail :: write_op :: operator()(const boost :: system :: error_code&,std :: size_t,int)[with AsyncWriteStream = boost :: asio :: basic_stream_socket; CompletionCondition = boost :: asio :: detail :: transfer_all_t; WriteHandler = boost :: _ bi :: bind_t,boost :: _ bi :: list3(*)(),boost :: _ bi :: va | \提升\ ASIO \ IMPL \ write.hpp | 585 |需要来自'void boost :: asio :: async_write(AsyncWriteStream&,const ConstBufferSequence&,WriteHandler&&)[with AsyncWriteStream = boost :: asio :: basic_stream_socket; ConstBufferSequence = boost :: asio :: mutable_buffers_1; WriteHandler = boost :: _ bi :: bind_t,boost :: _ bi :: list3(*)(),boost :: _ bi :: value,boost :: arg< 2> (*)()> >]'| \ iodata.cpp | 76 |从这里要求| \ boost \ bind \ bind.hpp | 392 |错误:无法调用'(boost :: _ mfi :: mf2)(const boost :: system :: error_code&,iodata *&,const unsigned int&)' | \ boost \ bind \ mem_fn_template.hpp | 253 |注意:候选人是:| \ boost \ bind \ mem_fn_template.hpp | 278 |注意:R boost :: _ mfi :: mf2 :: operator()(T *,A1,A2)const [with R = void; T = ioclient; A1 = const boost :: system :: error_code&amp ;; A2 = iodata *] | \ boost \ bind \ mem_fn_template.hpp | 278 |注意:参数1从'const boost :: system :: error_code'到'ioclient *'没有已知的转换 \ boost \ bind \ mem_fn_template.hpp | 283 |注意:模板R boost :: _ mfi :: mf2 :: operator()(U&,A1,A2)const [U = U; R =无效; T = ioclient; A1 = const boost :: system :: error_code&amp ;; A2 = iodata *] | \ boost \ bind \ mem_fn_template.hpp | 283 |注意:模板参数扣除/替换失败:| \ boost \ bind \ bind.hpp | 392 |注意:无法转换'(& a) - > boost :: _ bi :: list2 :: operator []((*&((boost :: _ bi :: list3) (*)(),boost :: _ bi :: value,boost :: arg< 2>()()> )this) - > boost :: _ bi :: list3(*) (),boost :: _ bi :: value,boost :: arg< 2>(*)()> ::。boost :: _ bi :: storage3(*)(),boost :: _ bi :: value,boost :: arg< 2>(*)()> ::。boost :: _ bi :: storage2(*)(),boost :: bi :: value> :: a2 )) '(输入'iodata *')输入'const boost :: system :: | \ boost \ bind \ mem_fn_template.hpp | 291 |注意:模板R boost :: _ mfi :: mf2 :: operator()(const U&,A1,A2)const [with U = U; R =无效; T = ioclient; A1 = const boost :: system :: error_code&amp ;; A2 = iodata *] | \ boost \ bind \ mem_fn_template.hpp | 291 |注意:模板参数扣除/替换失败:| \ boost \ bind \ bind.hpp | 392 |注意:无法转换'(& a) - > boost :: _ bi :: list2 :: operator []((*&((boost :: _ bi :: list3) (*)(),boost :: _ bi :: value,boost :: arg< 2>()()> )this) - > boost :: _ bi :: list3(*) (),boost :: _ bi :: value,boost :: arg< 2>(*)()> ::。boost :: _ bi :: storage3(*)(),boost :: _ bi :: value,boost :: arg< 2>(*)()> ::。boost :: _ bi :: storage2(*)(),boost :: bi :: value> :: a2 )) '(输入'iodata *')输入'const boost :: system :: | \ boost \ bind \ mem_fn_template.hpp | 299 |注意:R boost :: _ mfi :: mf2 :: operator()(T&,A1,A2)const [with R = void; T = ioclient; A1 = const boost :: system :: error_code&amp ;; A2 = iodata *] | \ boost \ bind \ mem_fn_template.hpp | 299 |注意:参数1从'const boost :: system :: error_code'到'ioclient&'|
没有已知的转换
我确信我在使用bind做错了,但是我对这可能是什么感到茫然。有什么想法吗?
答案 0 :(得分:4)
使用实例方法时,必须将this
指针作为第二个参数传递给bind()。
编辑:
我已经完成了你想用boost :: asio做的事情。以下是我实施的摘录:
boost::asio::async_write(
m_Socket,
boost::asio::buffer((const unsigned char *)(rMsg.c_str()), rMsg.length()),
boost::bind(&ServerToClientConnT::HandleAsioWrite,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
其中HandleAsioWrite的方法声明如下:
void HandleAsioWrite(const boost::system::error_code& rErrorCode,
std::size_t nBytesTransferred);
答案 1 :(得分:3)
初始示例失败,因为将调用成员函数的对象实例不会传递给bind
。这在编译器错误中表示,它指出没有从const boost::system::error_code
到ioclient*
的已知转换。
将Boost.Bind与成员指针一起使用时,记录为
boost::bind(&X::f, args)
相当于boost::bind<R>(boost::mem_fn(&X::f), args)
。
此外,Boost.mem_fn的文档说明:
它[
boost::mem_fn
]支持具有多个参数的成员函数指针,返回的函数对象可以将指针,引用或指向对象实例的智能指针作为其第一个参数< / b>
因此,如果boost::bind
的第一个参数是成员指针,那么:
boost::mem_fn
返回的函数对象的第一个参数。boost::bind
返回的函数对象必须在与_1
占位符匹配的参数位置传递对象实例句柄。例如,给定
struct Foo
{
void do_something(int x) {}
};
可以使用以下任何一个绑定和调用do_something
成员函数:
Foo f;
boost::bind(&Foo::do_something, &f, _1)(42); // handle is second argument.
boost::bind(&Foo::do_something, _1, _2)(&f, 42); // handle matches _1 position.
boost::bind(&Foo::do_something, _2, _1)(42, &f); // handle matches _1 position.
使用Boost.Asio,boost::asio::placeholders::error
实现为占位符_1
。因此,必须将对象实例作为第二个参数传递给bind
调用,或者必须将对象实例作为参数传递给自由函数或静态成员函数,然后调用成员函数在对象实例上。 Here是使用非静态成员函数编译的解决方案示例,但感兴趣的片段是:
ioclient client;
iodata data;
boost::asio::async_write(
socket,
boost::asio::null_buffers(),
boost::bind(&ioclient::handlermessagewrite,
&client,
boost::asio::placeholders::error,
&data,
boost::asio::placeholders::bytes_transferred));
compiler error响应中发布的Lou表示正在尝试使用ioclient
的实例句柄调用iodata
成员函数,这是一种不兼容的类型。要使iodata
成为兼容类型,必须从ioclient
继承。如果这是预期的类型层次结构,则验证继承是否正确。否则,请仔细匹配参数类型和位置与绑定的函数。