我学习了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
通过值传递(其值被复制)到SHOW
lambda中,因此它显示新地址a2 = 0x39f95b
。
我们调用FV
lambda,通过值捕获x
(其值被复制)。因此在FV
中,它有新的地址a3 = 0x39f950
。
从FV
我们调用SHOW
lambda。x
(来自FV
的作用域)是通过值传递的,所以在SHOW
中我们得到X - a4 = 0x39f8f8
的新地址。
我们调用FR
lambda通过引用捕获x
(这里没有值复制)。所以在FR
中,x
有地址a1 = 0x39f95c
-足够公平。
从FR
我们调用SHOW
lambda。x
(x
reference?)(来自FV
的作用域)是通过值传递的,所以在SHOW
内部我们得到新的...等等什么?x
的地址在这里是0x39f8f8 = a4
。
我不明白。据我所知,lambdas被编译为某种类,所以它们是内存中的对象。你可以看到我还记录了FV
和FR
中的SHOW
lambda地址。它们是不同的。这意味着这些SHOW
lambdas是不同的对象,所以它们内部的x
示例应该是不同的。但它不能使我得出任何结论。
有谁能解释一下我们如何在SHOW
中获得相同的地址?
1条答案
按热度按时间vuktfyat1#
您希望最外层作用域中的
x
副本的不同对象是同一个对象。下面是使用不同名称的副本的代码:
在输出中,虽然仍然有3个不同的
y
,因为show
被调用了3次(两次只是碰巧在同一个地址结束,但这只是偶然:正如在注解中提到的,打印相同的地址不仅仅是“偶然”。当一个函数返回时,它的堆栈被释放,可以被下一个调用的函数使用。你可以在这个例子中看到同样的效果:
Possible output: