#include<iostream>
using namespace std;
int main()
{
const int k = 10;
// Capture k by value
auto myl = [k] (int k) { cout << " ++k=" << ++k ; };
myl(k+10);
}
下面的错误
lamda.cpp: In lambda function:
lamda.cpp:10:50: error: increment of read-only variable âkâ
auto myl = [k] (int k) { cout << " ++K=" << ++k ; };
很明显,我指的是局部变量K,而不是const成员K。
答案 0 :(得分:4)
这并不像看起来那样简单。通过副本捕获k
的lambda等效于其闭包类型具有名为k
的成员以及具有定义使用指定参数和主体的operator()
的struct对象。如果从技术上讲是正确的,那么可以肯定,我们知道函数参数会隐藏类成员。
除非标准实际上不是这样定义lambda的。相反,它说任何由值捕获的实体都对应于闭包类型的 unnamed 成员。在lambda主体中,名称查找在lambda的包围范围内,而不是在闭合类型的范围内。如果该名称查找找到了由副本捕获的实体,则编译器必须在内部将名称的用法转换为未命名成员的用法。在C ++ 11和C ++ 14中,这些规则没有明确指定lambda参数名称如何适合该名称查找方案,结果,在以下情况下,不同的编译器和编译器版本在行为上没有达成共识:捕获的实体和lambda参数具有相同的名称。
使用Defect Resolution 2211,C ++ 17通过将其视为非法来解决了该问题:
[expr.prim.lambda.capture] / 5:
如果简单捕获中的标识符显示为 lambda-declarator的参数的 declarator-id , / em>的 parameter-declaration-clause ,该程序格式不正确。 [示例:
void f() { int x = 0; auto g = [x](int x) { return 0; } // error: parameter and simple-capture have the same name }
-示例]
(另请参见当前草稿镜中的the same paragraph。)