AFAIK,C 11/14在定义lambda时不允许原位定义新的返回类型.然而,似乎C 14 lambda捕获表达式基本上创建了一个或多个“成员”和一个operator()的匿名类型.那么为什么编译器不允许从lambda外面访问被捕获的成员.我的虚弱心灵不能处理C的复杂性,但它听起来像是一种合理的语言延伸?这是一个例子.
vector<string> words = { "Stack","Overflow" }; auto l = [w = words](){}; // almost like a C# anonymous type cout << l.w[0]; // does not work.
解决方法
现状
当将lambda init-captures添加到语言时,这是讨论过的.目前的标准工作草案(N3797)说(在[expr.prim.lambda] p11)中)
For every init-capture a non-static data member named by the identifier of the init-capture is declared in the closure type.
该标准没有指定该成员的访问权限,因此不清楚这是否有效:
auto x = [n(0)] {}; int k = x.n; // ok?
初始化捕获的这个和其他一些规范问题导致了标准草案的国家机构意见GB3,由C核心工作组处理为core issue 1760.在讨论这个问题时,核心工作组决定了lambda的init捕获不应该是关闭对象的可访问成员.
第1760号决议(经CWG批准但尚未由全体委员会批准)的规定将改为说明:
An init-capture behaves as if it declares and explicitly captures a variable of the form
“auto init-capture ;”
whose declarative region is the lambda-expression‘s compound-statement […]
这个新的措辞清楚地表明,init-capture不会添加一个可关闭的对象的成员,而是像其他的lambda捕获一样.
作为语言扩展
使init捕获成为关闭类型的可访问成员当然是可能的(并且我在clang中初始化初始化捕获的实现在我实现了问题1760的解决之前).它也似乎是一个有用的功能,但它也允许在初始化捕获不可见的常见情况下违反lambda表达式的封装.