[英]Access C++14 lambda captures like struct members
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-capture添加到语言时讨论了这个问题。 该标准的当前工作草案(N3797)说(在[expr.prim.lambda] p11中 ):
对于每个init-capture ,在闭包类型中声明由init-capture的标识符命名的非静态数据成员。
该标准未指定该成员的访问权限,因此不清楚这是否有效:
auto x = [n(0)] {};
int k = x.n; // ok?
初始捕获的这个和其他一些规范问题导致国家机构评论标准草案GB3,由C ++核心工作组作为核心问题1760处理 。 在这个问题的讨论,核心工作组决定,拉姆达的init-记录 不应该是封闭对象的可访问成员。
第1760期(由CWG批准但尚未由整个委员会批准)的决议改变了规范,改为:
init-capture的行为就好像它声明并显式捕获
“auto init-capture ;”
形式的变量,其声明区域是lambda-expression的复合语句 [...]
这个新的措辞清楚地表明, init-capture不会添加闭包对象的可命名成员,而是像任何其他lambda捕获一样。
作为语言扩展
使init-capture成为闭包类型的可访问成员当然是可能的(在我实现第1760期的解决方案之前,我在clang中初始实现init- capture)。 它似乎也是一个有用的功能,但它也允许在不应该看到init-capture的常见情况下违反lambda表达式的封装。
如果我理解这一点,你希望能够访问在lambda中捕获的变量。 但根据从lambda获取捕获变量的最佳答案? , 这是不可能的。
这是不可能的设计
5.1.2 [expr.prim.lambda]
15 [...]对于由副本捕获的每个实体,在闭包类型中声明一个未命名的非静态数据成员。 这些成员的声明顺序未指定。 [...]
16 [...]未指定是否在闭包类型中为通过引用捕获的实体声明了其他未命名的非静态数据成员。
捕获的变量是未命名的(或至少具有凡人无法形容的名称),并且故意未指定其声明顺序。 封闭类型中甚至可能不存在引用捕获。
大胆强调我的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.