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

时间:2014-11-01 19:03:34

标签: c++ c++11 lambda function-pointers

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

我想换句话说,lambda与&捕获列表和常规函数之间的功能差异是什么,使得lambda不能转换为函数指针?

2 个答案:

答案 0 :(得分:10)

所以让我们举一个琐碎的lambda的例子:

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

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

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

    Object& o;
};

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

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

答案 1 :(得分:3)

  

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

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