提问人:Vlad Zhukovsky 提问时间:3/26/2023 最后编辑:Benjamin BuchVlad Zhukovsky 更新时间:3/27/2023 访问量:96
C++:嵌套的 lambda 函数引用传递参数的相同地址
C++: nested lambda function refer same address of passed parameter
问:
我研究了 lambda,并在嵌套 lambda 函数时注意到了一些奇怪的事情。
int x{10}; // assume x has 0x1 address here
cout << "SCOPE: x address: " << &x << endl; // showing 0x1 for x address
auto show =
[](int x) {
cout << "SHOW: x address: " << &x << endl;
};
cout << "SCOPE: show-lambda address: " << &show << endl;
show(x); // showing 0x2 for x address
auto fv =
[x, show]() {
cout << "FV : x address: " << &x << " " << endl; // 0x3
cout << "FV : show-lambda address:" << &show << endl;
show(x); // showing 0x4 for x address
};
auto fr =
[&x, show]() {
cout << "FR : x address: " << &x << " " << endl; // showing 0x1 for x address
cout << "FR : show-lambda address:" << &show << endl;
show(x); // showing 0x4 for x address - WHY???
};
fv();
fr();
SCOPE: x address: 0x39f95c
SCOPE: show-lambda address: 0x39f95b
SHOW: x address: 0x39f928
FV : x address: 0x39f950
FV : show-lambda address:0x39f954
SHOW: x address: 0x39f8f8
FR : x address: 0x39f95c
FR : show-lambda address:0x39f948
SHOW: x address: 0x39f8f8
x
得到地址。a1 = 0x39f95c
x
按值(其值被复制)传递到 lambda 中,因此它显示新地址。SHOW
a2 = 0x39f95b
我们称之为 lambda capture by value(其值被复制)。所以里面有新的地址.FV
x
FV
a3 = 0x39f950
从我们称之为 lambda。 (from 的范围)是按值传递的,所以在里面我们得到新的地址FV
SHOW
x
FV
SHOW
X - a4 = 0x39f8f8
我们称之为 lambda 捕获的引用(此处没有值副本)。所以里面有地址 - 很公平。FR
x
FR
x
a1 = 0x39f95c
从我们称之为 lambda。 (参考?(从 的范围)是按值传递的,所以在里面我们得到新的......等什么?这里的地址是。FR
SHOW
x
x
FV
SHOW
x
0x39f8f8 = a4
我不明白。据我了解,lambda 被编译为某种类,因此它们是内存中的对象。你可以看到我还在里面记录了 lambda 地址和 .他们是不同的。这意味着这些 lambda 是不同的对象,因此它们内部的实例应该不同。但这不能让我得出任何结论。SHOW
FV
FR
SHOW
x
谁能解释一下我们是如何在里面获得相同的地址的?FR
SHOW
答:
您期望在最外层范围内只是副本的不同对象是同一对象。x
以下是对副本使用不同名称的代码:
#include <iostream>
using std::cout;
using std::endl;
int main() {
int x {10};
cout << "SCOPE: x address: " << &x << endl; // this is x
auto show = [](int y)
{
cout << "SHOW: y address: " << &y << endl;
};
cout << "SCOPE: show-lambda address: " << &show << endl;
show(x); // copy x
auto fv = [ z = x, show]() // copy x
{
cout << "FV : z address: " << &z << " " << endl;
show(z); // copy x again
};
auto fr = [&x, show]()
{
cout << "FR : x address: " << &x << " " << endl; // this is x, because captured as reference
show(x); // copy x
};
fv();
fr();
}
在输出中,虽然仍然有 3 个不同,因为被调用了 3 次(两次只是碰巧在同一个地址结束,但这只是偶然的:y
show
SCOPE: x address: 0x7ffe1f6d067c
SCOPE: show-lambda address: 0x7ffe1f6d067b
SHOW: y address: 0x7ffe1f6d0644
FV : z address: 0x7ffe1f6d0670
SHOW: y address: 0x7ffe1f6d0624
FR : x address: 0x7ffe1f6d067c
SHOW: y address: 0x7ffe1f6d0624
正如评论中提到的,打印相同的地址不仅仅是“偶然”。当函数返回时,其堆栈将被释放,并可由下一个调用的函数使用。你可以在这个例子中看到同样的效果:
#include <iostream>
void foo() {
int x = 42;
std::cout << &x << "\n";
}
int main() {
foo();
foo();
}
0x7ffddcc6fd9c
0x7ffddcc6fd9c
评论
show(x);
show::x
show(x)
show
fv()
fr()
x
show
show
fv()
show
fr()
上一个:带循环队列的遍历二叉搜索树
下一个:如何按值将变量传递给另一个线程?
评论