C++ 为什么不是';通过引用捕获变量的lambda是否可转换为函数指针?

C++ 为什么不是';通过引用捕获变量的lambda是否可转换为函数指针?,c++,c++11,lambda,function-pointers,C++,C++11,Lambda,Function Pointers,如果我有一个lambda,它通过引用捕获所有自动变量([&]{}),为什么不能将它转换为函数指针?常规函数可以修改变量,就像通过引用捕获所有内容的lambda一样,为什么不一样呢 换言之,我想,具有捕获列表的lambda与常规函数(lambda不能转换为函数指针)之间的功能区别是什么 Object o; auto foo = [&]{ return o; }; foo的类型是什么?它可能看起来像这样: struct __unique_unspecified_blah { ope

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


换言之,我想,具有捕获列表的lambda与常规函数(lambda不能转换为函数指针)之间的功能区别是什么

Object o;
auto foo = [&]{ return o; };
foo
的类型是什么?它可能看起来像这样:

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

    Object& o;
};

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

问题的“引用”部分不相关-如果lambda捕获了任何内容,那么它的
操作符()
将需要引用对象中的某种存储。如果它需要存储,则无法转换为原始函数指针

换言之,我想,a和B之间的功能区别是什么 lambda具有
&
捕获列表和常规功能,以便 lambda不能转换为函数指针


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

所有这些捕获变量的引用(实际上是指针)都必须存储在某个地方。将“通过引用捕获”视为“通过值捕获地址”。@IgorTandetnik:如果我们使用GC(可能但很少)或接受内存泄漏,这是可以解决的。@重复数据消除程序:我想编译器可以在运行时动态生成程序集thunk;我已经看过了(如果你想知道的话,是微软的ATL)。但这在按价值捕获时同样有效;引用引用既不帮助也不伤害。@ IGORTANTDENK:当然,我忽略了OPS固定在引用。这是唯一的东西,你想知道的C++ LAMBDAS?我有一个更基本的问题:为什么明确禁止写下lambda的类型?您可以将其分配给
auto
变量或将其类型作为模板参数传递,但仅此而已。根本没有语法来编写接受lambda的非模板函数。lambda的类型是唯一不能写下来的类型,这使得它们不如二等公民。就我个人而言,如果一种语言功能是如此的基本,我不会再去考虑它。这与你不能将一个典型的类方法转换成一个原始函数指针的原因是一样的。不,这是一个调用约定。现在,如果你想要一个需要更少参数的原始函数指针(比如不需要
这个
)。@重复数据消除:我认为这正是他在剩下的解释中的意思…@EdS:只是G++很乐意为你将成员函数指针转换为常规函数指针,它们工作起来很顺利。@deplicator:我想是非虚拟的吧?我不太明白它在一般情况下是如何工作的。@重复数据消除或如何将成员函数指针转换为常规函数指针?我认为它们是不同的类型(比如
void(*)(
vs
void(Obj::*)()
)@Deduplicator我并没有试图说这是完全不可能的,因为你可以做一些很好的技巧(例如,使用静态贴图)。我将尝试创建一个示例。稍后将查找它。