如果我有一个lambda通过引用([&] {}
)捕获所有自动变量,为什么不能将它转换为函数指针?常规函数可以修改变量,就像lambda一样,通过引用可以捕获所有内容,为什么它不一样呢?
我想换句话说,lambda与&
捕获列表和常规函数之间的功能差异是什么,使得lambda不能转换为函数指针?
答案 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可以,因为可以捕获所需的每个变量。
换句话说:常规功能没有状态。具有捕获变量的闭包对象确实具有状态。因此闭包对象不能简化为常规函数,因为状态会丢失。