为什么通过引用捕获变量的 lambda 不能转换为函数指针?

Why isn't a lambda that captures variables by reference convertible to a function pointer?

本文关键字:转换 不能 函数 指针 lambda 引用 变量 为什么      更新时间:2023-10-16

如果我有一个lambda,它通过引用捕获所有自动变量([&] {}),为什么不能将其转换为函数指针?正则函数可以修改变量,就像lambda通过引用捕获所有内容一样,那么为什么它不一样呢?

换句话说,我想,具有&捕获列表的lambda和常规函数之间的函数区别是什么,这样lambda就不能转换为函数指针?

因此,让我们以一个平凡的lambda:为例

Object o;
auto foo = [&]{ return o; };

foo的类型是什么?它可能看起来像这样:

struct __unique_unspecified_blah
{
    operator()() const {
        return o;
    }
    Object& o;
};

你能创建一个指向那个operator()的函数指针吗?不,你不能。该函数需要一些来自其对象的额外信息。这与您无法将典型的类方法转换为原始函数指针的原因相同(如果没有this所在的额外第一个参数)。假设你确实创建了一些this指针,它怎么知道从哪里获取o

问题的"引用"部分并不相关——如果lambda捕获了任何东西,那么它的operator()将需要引用对象中的某种存储。如果它需要存储,则无法转换为原始函数指针。

我想换句话说lambda具有&捕获列表和正则函数,使得lambda不能转换为函数指针?

引用虽然不是对象,但需要存储在某个地方。一个正则函数不能访问另一个函数的局部变量;仅引用可以引用局部变量的引用(例如,作为参数)。以&作为捕获默认值的Lambda可以,因为可以捕获所需的每个变量
换句话说:一个正则函数没有状态。具有捕获变量的闭包对象确实具有状态。因此,闭包对象不能简化为正则函数,因为状态会丢失。