简体   繁体   English

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

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

If I have a lambda which captures all automatic variables by reference ( [&] {} ), why can't it be converted to a function pointer? 如果我有一个lambda通过引用( [&] {} )捕获所有自动变量,为什么不能将它转换为函数指针? A regular function can modify variables just like a lambda that captures everything by reference can, so why is it not the same? 常规函数可以修改变量,就像lambda一样,可以通过引用捕获所有内容,为什么它不一样?

I guess in other words, what is the functional difference between a lambda with a & capture list and a regular function such that the lambda is not convertible to a function pointer? 我猜换句话说,lambda与& capture列表和常规函数之间的功能区别是什么,lambda不能转换为函数指针?

So let's take the example of a trivial lambda: 让我们以一个普通的lambda为例:

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

What does the type of foo look like? foo的类型是什么样的? It might look something like this: 它可能看起来像这样:

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

    Object& o;
};

Can you create a function pointer to that operator() ? 你能创建一个指向该operator()的函数指针吗? No, you can't. 不,你不能。 That function needs some extra information that comes from its object. 该函数需要一些来自其对象的额外信息。 This is the same reason that you can't convert a typical class method to a raw function pointer (without the extra first argument where this goes). 这是一个你不能一个典型的类方法转换为原始函数指针(没有额外的第一个参数,其中同样的原因this行)。 Supposing you did create some this pointer - how would it know where to get o from? 假设你确实创建了一些这个指针 - 它怎么知道从哪里获得o

The "reference" part of the question is not relevant - if your lambda captures anything , then its operator() will need to reference some sort of storage in the object. 问题的“参考”部分是不相关的 - 如果你的lambda捕获任何东西 ,那么它的operator()将需要在对象中引用某种存储。 If it needs storage, it can't convert to a raw function pointer. 如果需要存储,则无法转换为原始函数指针。

I guess in other words, what is the functional difference between a lambda with a & capture list and a regular function such that the lambda is not convertible to a function pointer? 我猜换句话说,lambda与& capture列表和常规函数之间的功能区别是什么,lambda不能转换为函数指针?

References, though they aren't objects, need to be stored somewhere. 引用虽然不是对象,但需要存储在某个地方。 A regular function cannot access local variables of another function; 常规函数不能访问另一个函数的局部变量; Only references (eg as parameters) that could refer to local variables. 仅引用可引用局部变量的引用(例如,作为参数)。 A Lambda with a & as the capture-default can, because every variable needed can be captured. 具有&作为捕获默认值的Lambda可以,因为可以捕获所需的每个变量。
In other words: A regular function doesn't have state. 换句话说:常规函数没有状态。 A closure object with captured variables does have state. 具有捕获变量的闭包对象确实具有状态。 So a closure object cannot be reduced to a regular function, because the state would be lost. 因此闭包对象不能简化为常规函数,因为状态会丢失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM