gpt4 book ai didi

c++ - 将 lambda 与自动声明结合使用还是就地使用?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:03:41 26 4
gpt4 key购买 nike

我正在尝试学习现代 C++,并且正在使用 Boost.Asio 进行联网。我写了一个TCP连接类,它使用了Asio的异步操作。这是目前我从套接字读取数据的方法:

template<class T>
inline auto connection<T>::read(size_t length) -> void
{
auto handler = [&](const boost::system::error_code& error, size_t bytes_transferred) {
if (error == boost::asio::error::eof or error == boost::asio::error::connection_reset) {
close();
} else {
on_read(bytes_transferred);
}
};
socket.async_read_some(boost::asio::buffer(read_buffer, length), handler);
}

这里我用 auto 单独声明了读取处理程序,因为我认为它看起来比就地 lambda 更具可读性,即

template<class T>
inline auto connection<T>::read(size_t length) -> void
{
socket.async_read_some(boost::asio::buffer(read_buffer, length), [&](const boost::system::error_code& error, size_t bytes_transferred) {
if (error == boost::asio::error::eof or error == boost::asio::error::connection_reset) {
close();
} else {
on_read(bytes_transferred);
}
});
}

但是我在第一个版本中遇到了段错误,我相信这是因为当方法超出范围时处理程序 lambda 丢失了。然后我尝试使用 std::move 移动处理程序

socket.async_read_some(boost::asio::buffer(read_buffer, length), std::move(handler));

这似乎修复了段错误。

现在我的问题是:与就地使用第一个版本(使用 std::move)相比,是否存在任何性能或其他问题?您认为哪种做法更好?

最佳答案

这两个代码示例都应该有效。第一个示例将处理程序作为左值传递,在这种情况下,实现将制作一个拷贝。第二个示例将 lambda 作为纯右值传递,在这种情况下,实现将执行移动构造。由于左值和纯右值都是微不足道的,因此这两个操作是相同的。

Networking TS(以及 Asio 和 Boost.Asio)中的异步启动函数通过执行“衰减复制”来获取处理程序的所有权。这意味着根据参数是否为左值来复制或移动处理程序。

我不确定为什么您的第一个示例会崩溃,但这与 lambda 的生命周期无关。出于显而易见的原因,异步启动函数从不通过引用接收句柄,并且始终通过衰减复制获得所有权。

你的代码一定有其他问题,在你没有粘贴的部分。例如,在函数返回后,是什么让连接对象保持事件状态?

关于c++ - 将 lambda 与自动声明结合使用还是就地使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54797568/

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