为什么我返回 lambda 的函数似乎被转换为将 int 转换为 int 的函数?

Why does my function which returns a lambda seem to be transformed into a function which turns an int?

提问人:Chris_F 提问时间:1/1/2023 更新时间:1/1/2023 访问量:66

问:

给定以下返回 lambda 的函数

auto foo(int y) {
    return [=](int x) { return x + y; };
}

GCC 和 Clang 生产以下程序集

foo(int):
    mov     eax, edi
    ret

据我所知,这相当于这个

int bar(int n) {
    return n;
}

但似乎按预期运行。bar

auto fn = foo(2);
std::cout << fn(3); //prints 5
C++ Lambda 闭包

评论

0赞 user12002570 1/1/2023
as-if 规则允许 comiler 执行任何操作,只要观察到的行为相同。您返回一个 lambda,因此也是一个 lambda。foofn
0赞 Chris_F 1/1/2023
@JasonLiam数字 2 如何等价于接受整数并返回和整数的闭包?
0赞 273K 1/1/2023
如果你看一下完全优化的汇编程序,那由你看到的不是被调用的。编译器将其删除,只保留不执行任何操作的符号,mov esi, 5foo
0赞 Chris_F 1/1/2023
即使使用 -O0 似乎也是一个空操作。foo
0赞 273K 1/1/2023
如何使用 -O0 进行无操作? 在堆栈上分配一个对象,并将参数保留在该对象中。foo

答:

3赞 Artyer 1/1/2023 #1

请记住,闭包类型是类类型。您的函数类似于以下内容:

auto foo(int y) {
    // return [=](int x) { return x + y; };
    struct closure_type {
        int y;
        auto operator()(int x) const { return x + y; }
    };
    return closure_type{ y };
}

而且,一旦删除了类型,返回 int 和返回具有单个 int 数据成员的普通结构之间实际上没有区别。

如果您更改了类型,您将对 int 返回函数有完全相同的体验:

using closure_type = decltype(foo(int{}));
auto fn = std::bit_cast<closure_type>(bar(2));
std::cout << fn(3); //prints 5

评论

0赞 madhur4127 1/1/2023
最后一个片段中有什么?bar
0赞 Chris_F 1/1/2023
谢谢。即使我知道捕获 lambda 的实现方式类似于函子,但我仍然想将其视为函数指针。