C++ lambda捕获变量的规则
例如:C++ lambda捕获变量的规则,c++,visual-c++,lambda,c++11,g++,C++,Visual C++,Lambda,C++11,G++,例如: class Example { public: explicit Example(int n) : num(n) {} void addAndPrint(vector<int>& v) const { for_each(v.begin(), v.end(), [num](int n) { cout << num + n << " "; }); } private: int num; };
class Example
{
public:
explicit Example(int n) : num(n) {}
void addAndPrint(vector<int>& v) const
{
for_each(v.begin(), v.end(), [num](int n) { cout << num + n << " "; });
}
private:
int num;
};
int main()
{
vector<int> v = { 0, 1, 2, 3, 4 };
Example ex(1);
ex.addAndPrint(v);
return 0;
}
类示例
{
公众:
显式示例(intn):num(n){}
无效添加和打印(矢量和v)常量
{
对于每个(v.begin(),v.end(),[num](int n){cout标准规定如下(5.1.2):
使用非限定名称查找的常规规则(3.4.1)查找捕获列表中的标识符;每个
此类查找应找到一个变量,该变量的自动存储持续时间声明在本地文件的到达范围内
lambda表达式
据我所知,GCC编译器是正确的,因为“num”在lambda声明点处于到达范围内。5.1.2/9:
局部lambda表达式的到达范围是
封闭范围包括最里面的封闭函数
及其参数
和5.1.2/10:
捕获列表中的标识符是使用常规规则查找的
对于非限定名称查找(3.4.1);每次此类查找应找到一个
变量中声明了自动存储持续时间
局部lambda表达式的作用域
由于num
既没有在任何函数作用域中声明,也没有自动存储持续时间,因此无法捕获。因此VS是对的,g++是错的。请注意,您必须在此处通过值捕获this
,而不是num
。当您使用num
时,实际上是在使用this->num
。还请注意,MSVC没有实现lambdas的C++11措辞,因为它在2008年实现所有这些之后发生了变化。@Alexandre:捕获this
实际上与通过引用捕获num
是一样的。这似乎不是这里想要的。@Ben:很好。但是这里的结果是一样的,因为闭包没有逃逸 addAndPrint
的范围(无论如何,整个内容都可能在这里内联).5.1.2正如@dimitri引用的那样,似乎表明MSVC是正确的,因为num
不是一个具有自动存储持续时间的变量。然而,这种行为非常奇怪。它不足以在范围内,它必须是一个具有自动存储持续时间的变量。感谢您的澄清。我发现g++4.6.2在ng捕获,例如,[=,this]
也进行编译,他们计划在4.7.0中修复它们。