c++ - c ++:为什么必须通过lambda中的值捕获特定参数
问题描述
#include <iostream>
#include <functional>
#include <utility>
using namespace std;
typedef std::function<void(const string&, const string&, const bool, const bool)>
Callback_T;
class A {
public:
void
process(const string &a, const string &b, const bool c, const bool d, const int e)
{
cout << "a: " << a << " b: " << b << " c: " << c << " d: " << d << " e: " << e << endl;
}
Callback_T
constructCallback(const int &e)
{
Callback_T callback =
[&, this, e](auto&&...args) // <--- here, e must be captured by value, why?
{
this->process(
std::forward<decltype(args)>(args)...,
e);
};
return callback;
}
};
int main()
{
A a;
auto cb = a.constructCallback(20);
cb("A", "B", true, false);
}
上面的程序输出:“a:A b:B c:1 d:0 e:20”但是如果我将捕获e的那一行更改为:
[&,这个,&e]
它输出:“a:A b:B c:1 d:0 e:26340408 ”,似乎表明e未定义/初始化。
为什么只通过价值作品来捕捉它?
解决方案
你所拥有的是一个悬空的参考。由于e
是参考参数,因此它绑定到其他东西。在这种情况下,它是从文字创建的临时对象20
。当函数结束callback
并引用不再存在的对象时,此临时值超出范围。
当您按值捕获时,您会否定这个问题,因为 lambda 将存储它自己的副本,以e
确保它在constructCallback
返回后仍然有效。
通过引用捕获时,您必须确保没有路径会留下对不存在的东西的引用。
推荐阅读
- javascript - 在什么情况下 'a != a' 在 JavaScript 中解析为 true?
- reactjs - Ngrok 不断与 Nextjs 重新连接
- certificate - 为什么 NET::ERR_CERT_COMMON_NAME_INVALID 在 admin.localhost 上出现 chrome 错误,SAN 和 CN 设置为 *.localhost
- android - 如何每天重置计步器?
- http - 可以利用 Content-length 标头吗?
- android - Android loadThumbnail 专辑插图 (API 29)
- javascript - 屏幕共享不适用于 getDisplayMedia
- r - 为 POSIXct 日期格式添加因子列
- php - 找不到常量 subresourceOperations,类 App\Entity\Comment
- python - 有没有办法利用 asyncio 的多个 CPU 内核?