lambda表达式(MSVC ++ vs g ++)

时间:2010-07-09 08:44:04

标签: c++ visual-c++ lambda c++11 visual-c++-2010

我有以下代码

#include <algorithm>
#include <iostream>
#include <vector>
#include <functional>


int main()
{
  typedef std::vector<int> Vector; 
  int sum=0;
  Vector v;
  for(int i=1;i<=10;++i)
     v.push_back(i);

  std::tr1::function<double()>  l=[&]()->double{

    std::for_each(v.begin(),v.end(),[&](int n){sum += n; //Error Here in MSVC++});
    return sum;
     };

  std::cout<<l();
  std::cin.get();
}

上面的代码在MSVC++ 10上产生错误,而它与g++ 4.5编译良好。 产生的错误是1 IntelliSense: invalid reference to an outer-scope local variable in a lambda body c:\users\super user\documents\visual studio 2010\projects\lambda\lambda.cpp 19 46 lambda

那么,是否有其他方法可以访问外部作用域变量sum而无需在本地lambda表达式(std::for_each内)中显式创建新变量?

g++ 4.5上,代码编译得很好。 标准(n3000草案)是否说了什么?(我目前没有C ++ - 0x(1x?)标准的副本)

4 个答案:

答案 0 :(得分:15)

您是否真的尝试过编译问题中的代码? Visual C ++ 2010接受代码(显然删除了注释),并成功编译代码而没有错误。

您看到的“错误”不是编译错误,而是IntelliSense错误。 IntelliSense错误检查会导致很多误报(我在过去几个月中报告过Microsoft Connect上的一些错误);在这种情况下,IntelliSense错误地说这不是错误。

您有两种选择:可以忽略IntelliSense误报,也可以禁用IntelliSense错误检查(右键单击错误列表窗口并取消选中“显示IntelliSense错误”)。

无论哪种方式,这些IntelliSense错误都不会阻止编译成功。

答案 1 :(得分:1)

无论VC是错还是正确,你在(外)lambda之外声明的总和都是不好的风格。由于返回sum的值,因此无需在循环内更改外部变量的值。相反,你应该:

int sum = 0;
std::for_each(v.begin(),v.end(),[&](int n){sum += n;});
return sum;

可能是嵌套的lambdas也让VC感到困惑。我会说嵌套lambda是不合适的,并且使代码的可读性降低。

答案 2 :(得分:0)

我认为您可能必须在sum上明确声明闭包,如下所示:

std::for_each(v.begin(),v.end(),[&sum](int n){sum += n;});

通常,您应该被允许在本地范围内隐式捕获变量,但只要保证lambda在同一范围内运行。可能是因为你将lambda分配给一个函数var并在以后执行它(而不是直接运行它),MSVC不够聪明,无法理解该条件成立 - 毕竟,你可能会传递l并在其他范围内执行 - 因此它需要显式捕获声明。

答案 3 :(得分:0)

我认为你唯一的问题是蚂蚁大小的红波...... 由于微软早些时候已经发布了编译器,很快标准组织确实改变了名称查找的规则......所以intellisense不是最新的........

因为这个想法真的很可爱...... BABY ......

#include <algorithm>
#include <iostream>
#include <vector>
#include <functional>


int main()
{
  typedef std::vector<int> Vector; 
  int sum=0;
  Vector v;
  for(int i=1;i<=10;++i)
     v.push_back(i);

  std::tr1::function<double()>  l=[&]()->double{
      int *y; y=&sum;
      std::for_each(v.begin(),v.end(),[&](int n){*y += n; });
    return sum;
     };

  std::cout<<l();
  std::cin.get();
}