6

次のコードがあります

#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では、ローカル ラムダ式 (inside ) 内に新しい変数を明示的に作成せずに、outer-scope 変数にアクセスする他の方法はありますstd::for_eachか?

コード上g++ 4.5で正常にコンパイルされます。標準 (n3000 ドラフト) はそれについて何か言っていますか? (現在、C++-0x(1x ?) 標準のコピーを持っていません)

4

4 に答える 4

15

質問のコードを実際にコンパイルしてみましたか? Visual C++ 2010 はコードをそのまま受け入れ (明らかにコメントは削除されています)、エラーなしでコードを正常にコンパイルします。

表示されている「エラー」はコンパイル エラーではなく、IntelliSense エラーです。IntelliSense のエラー チェックでは、多くの誤検知が発生します (過去数か月にわたって、Microsoft Connect に関するいくつかのバグを報告しました)。この場合、IntelliSense は、エラーではないのにエラーであると誤って言っています。

IntelliSense の誤検知を無視するか、IntelliSense エラー チェックを無効にする ([エラー一覧] ウィンドウを右クリックし、[IntelliSense エラーを表示する] をオフにする) という 2 つのオプションがあります。

いずれにせよ、これらの IntelliSense エラーがコンパイルの成功を妨げることは決してありません。

于 2010-07-11T05:18:29.627 に答える
1

VC が間違っているか正しいかに関係なく、(外側の) ラムダの外で sum を宣言するのは悪いスタイルです。sum の値を返すため、ループ内で外部変数の値を変更する必要はありません。代わりに、次のものが必要です。

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

ネストされたラムダが VC を混乱させている可能性もあります。ネストされたラムダを持つのはやり過ぎであり、コードが読みにくくなります。

于 2010-07-11T02:09:01.907 に答える
0

sum次のように、クロージャを明示的に宣言する必要があると思います。

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

一般に、ローカルスコープで変数を暗黙的にキャプチャすることが許可されているはずですが、ラムダが同じスコープで実行されることが保証されている場合に限ります。おそらく、ラムダを関数varに割り当てて、後で実行するため(直接実行するのではなく)、MSVCは、その条件が成立することを理解するのに十分なほど賢くありません-結局のところ、lいくつかの場所でラムダを渡して実行する可能性があります他のスコープ-したがって、明示的なキャプチャ宣言が必要です。

于 2010-07-09T08:53:09.843 に答える
0

あなたが抱えている唯一の問題は、そのアリサイズの赤い波にあると思います....マイクロソフトがコンパイラを以前にリリースし、すぐに標準化団体が名前検索のルールを変更したため...インテリセンスは最新ではありません.... ....

だから、このアイデアを試してみてください.....赤ちゃん...

#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();
}
于 2010-07-22T22:17:37.813 に答える