C++:嵌套的 lambda 函数引用传递参数的相同地址

问题描述 投票:0回答:1

我研究了 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 引用???)(来自 FV 的范围)按值传递,所以在 SHOW 中我们得到新的...等等什么??? X在这里的地址是0x39f8f8 = a4.

我不明白。据我了解,lambda 被编译为某种类,因此它们是内存中的对象。你可以看到我还在 FV 和 FR 中记录了 SHOW-lambda 地址。他们是不同的。这意味着这些 show-lambda 是不同的对象,因此它们内部的 X 实例应该不同。但它无法让我得出任何结论。

任何人都可以解释我们如何在 SHOW 中的 FR 中获得相同的地址吗?

c++ lambda nested pass-by-value
1个回答
0
投票

你期望不同的对象只是最外层范围内

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 个不同的

y
因为
show
被调用了 3 次(两次恰好在同一个地址结束,但这只是偶然:

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
© www.soinside.com 2019 - 2024. All rights reserved.