lambda expression (MSVC++ vs g++)

…衆ロ難τιáo~ 提交于 2019-12-08 21:50:53

问题


I have the following code

#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();
}

The above code produces an error on MSVC++ 10 whereas it compiles fine with g++ 4.5. The error produced is 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

So, is there any other way to access the outer-scope variable sum without explicitly creating a new variable inside the local lambda expression(inside std::for_each)?

On g++ 4.5 the code compiles fine. Does the standard(n3000 draft) say anything about it?(I don't have a copy of C++-0x(1x ?) standard at present)


回答1:


Have you actually tried compiling the code in the question? Visual C++ 2010 accepts the code, as is (with the comment removed, obviously), and successfully compiles the code without error.

The "error" you are seeing is not a compilation error, but an IntelliSense error. The IntelliSense error checking results in a lot of false positives (I've reported several bugs on Microsoft Connect over the past few months); in this case, IntelliSense is incorrectly saying this is an error when it is not.

You have two options: you can ignore the IntelliSense false positives or you can disable the IntelliSense error checking (right-click the Error List window and uncheck "Show IntelliSense Errors").

Either way, these IntelliSense errors in no way prevent compilation from succeeding.




回答2:


Regardless of whether VC is wrong or right, it's bad style that you have sum declared outside your (outer) lambda. Since you return the value of sum, there's no need to be changing the value of an outer variable inside the loop. Instead, you should have:

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

It could be that the nested lambdas are confusing VC, too. I'd say it's overkill to have nested lambdas, and makes for less readable code.




回答3:


I think you may have to explicitly declare the closure over sum, like so:

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

In general, you're supposed to be allowed to implicitly capture variables in the local scope, but only as long as the lambda is guaranteed to run in the same scope. Possibly because you're assigning your lambda to a function var and executing it later (instead of just running it directly), MSVC isn't smart enough to understand that that condition holds - after all, you could potentially pass l and execute it in some other scope - so it requires the explicit capture declaration.




回答4:


I think the sole problem you have is with that ant size red wave.... SINCE microsoft had released the compiler earlier and soon the standards body did change the rule for name look up ...so intellisense isnt upto date........

SO TRY HITTING WITH THIS IDEA.....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();
}


来源:https://stackoverflow.com/questions/3211130/lambda-expression-msvc-vs-g

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!