Sockets asio反应堆内lambda使用auto与typedef的对比
我有一些这样的代码:Sockets asio反应堆内lambda使用auto与typedef的对比,sockets,c++11,lambda,boost-asio,Sockets,C++11,Lambda,Boost Asio,我有一些这样的代码: typedef std::function<void (void)> const& basic_callback_t; void Receive::async_basic(fragmenting_socket& socket, const ID id, basic_callback_t fn) { int buffer[1024]; socket.async_receive(buffer, sizeof(buffer), [&](con
typedef std::function<void (void)> const& basic_callback_t;
void Receive::async_basic(fragmenting_socket& socket, const ID id, basic_callback_t fn)
{
int buffer[1024];
socket.async_receive(buffer, sizeof(buffer), [&](const boost::system::error_code& ec, size_t bytes)
{
....
if (fn)
{
fn();
} else
{
THROW("async_receive callback: Could not call fn()");
}
});
}
上面的代码似乎工作正常,f
gets被调用,finished被设置为true。但是,如果我将匿名lambda传递到async_basic
或声明f
为
auto f = [&] () ....
然后asio反应器将fn
内部async\u receive
视为超出范围,并调用THROW()
语句。有人知道为什么会这样吗?实际上,我不明白为什么专门声明f
为protocol::basic\u callback\u t
有效而声明为auto
无效。在这两种情况下,函子都放在堆栈上,并且应该在运行m_服务
的线程中超出范围
我正在使用g++4.8.2编译,其中设置了-std=c++11标志集和-fPIC
干杯
Ben在这两种变体中 对
async\u receive
的调用通过引用捕获fn
。但是,只要async\u basic
返回,该引用就会失效
这同样适用于缓冲区[]
事实上:缓冲区
超出范围,因此在异步接收
写入时有未定义的行为
UB的本质是任何事情都有可能发生,这解释了为什么您会看到不同的行为。那么我如何将fn放在堆中,使其不超出范围?谢谢b通常的模式是从这个类中获得一个表示连接/传输顺序的
启用\u共享\u。然后,该类可以拥有缓冲区(以及其他类似state的东西)。对于完成处理程序,您不需要做特殊的事情,只需要不通过引用捕获函数
,谢谢您的帮助。你能给我举个例子吗?我在这里查找了enable_shared_,这是传递类的shared_ptr的一种方法。我想最安全的方法是创建一个函子,而不是lambda,在堆上创建一个函子,并将其传递给其他人……我的许多答案都说明了这一点。事实上,我在年的最新回答中也进行了非常类似的讨论和讨论。这里有一个搜索让你开始:谢谢。我是通过socket.async\u receive(buffer,sizeof(buffer),[&buffer,id,fn](const boost::system::error\u code&ec,size\u t bytes)获得的{….我通过值传递了std::函数,它成功了。缓冲区仍然不正确,但至少它不是一个拦截器。奇怪的是,认为每个lambda闭包都需要智能指针和小心地通过值传递,而不是通过引用传递,以保持正确性。
auto f = [&] () ....
void Receive::async_basic(fragmenting_socket& socket, const ID id, basic_callback_t fn)
{
int buffer[1024];
socket.async_receive(buffer, sizeof(buffer), [&](const boost::system::error_code& ec, size_t bytes)
{
if (fn) {
fn();
} else {
THROW("async_receive callback: Could not call fn()");
}
});