2010-07-09 45 views
6

我有以下代碼lambda表達式(MSVC++ VS克++)

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

而它編譯罰款與g++ 4.5以上代碼生成上MSVC++ 10錯誤。 產生的誤差是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代碼編譯得很好。 (我現在沒有C++ - 0x(1x?)標準的副本)

+1

VS10 doees有一些已知的與lambda捕獲範圍有關的bug,在這種情況下最有可能GCC是正確的。 – jalf 2010-07-09 09:12:47

+0

只需下載最近的標準草案 - 在Google上尋找「C++標準」,即可爲您提供鏈接。這是一個有趣的學習經驗,看看它:) – 2010-07-09 10:26:47

+2

請注意,最新的草案是FCD,N3092,你可以[從WG21網站下載](http://www.open-std.org/jtc1/ sc22/wg21/docs/papers/2010/n3092.pdf)(**警告:10.5MB PDF **)。 – 2010-07-11 04:56:48

回答

15

你真的試過編譯問題中的代碼嗎? Visual C++ 2010按原樣接受代碼(顯然,註釋已被刪除),併成功編譯代碼而不會出錯。

您看到的「錯誤」不是編譯錯誤,而是智能感知錯誤。 IntelliSense錯誤檢查會導致很多誤報(我在過去幾個月中報告過Microsoft Connect的一些錯誤);在這種情況下,智能感知不正確地說這是一個錯誤,當它不是。

您有兩種選擇:您可以忽略智能感知誤報,或者可以禁用智能感知錯誤檢查(右鍵單擊錯誤列表窗口並取消選中「顯示智能感知錯誤」)。

無論哪種方式,這些IntelliSense錯誤都不會阻止編譯成功。

0

我想你可能不得不明確宣佈關閉sum,像這樣:

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

一般情況下,你應該被允許隱式捕捉變量在局部範圍內,但只只要拉姆達是保證在同一範圍內運行。可能是因爲你將lambda分配給函數var並稍後執行它(而不是直接運行它),MSVC不夠聰明,無法理解該條件成立 - 畢竟,您可能會通過l並在其中執行它一些其他範圍 - 所以它需要明確的捕獲聲明。

1

無論VC是錯的還是正確的,在外部lambda表達式之外聲明的總和是壞風格。既然你返回sum的值,那麼就不需要改變循環內的外部變量的值。相反,你應該有:

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

這可能是因爲嵌套lambdas令VC感到困惑。我會說,嵌套lambdas是有點矯枉過正,並且使代碼更少可讀。

0

我認爲你唯一的問題就是那個螞蟻大小的紅色波...... SINCE微軟早些時候發佈了編譯器,很快標準體確實改變了名稱查找的規則......所以intellisense不是upto日期........

所以試着打這個想法..... 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(); 
} 
+0

我已經得到了答案並解決了我的問題。順便說一句,這裏不需要使用raw_pointer。即使提到總和也能解決問題。順便說一句,你可以關閉'show intellisense errors'選項。我希望你知道這一點。然而,代碼在技術上是正確的,所以我在這裏也提到它:http://stackoverflow.com/questions/3221812/sum-of-elements-in-a-vector/3221813#3221813 – 2010-07-23 02:25:33

+0

如果你的代碼在技術上是正確的我沒有找到一個理由在這裏張貼這樣愚蠢的錯誤在論壇上......我想如果你是一個好的程序員,你不會在公共場合拍麪包,所以所有的狗都會在那之後運行,(類比於成員這個論壇)... 他們嘗試討論的事情,而不是幫助........ – perilbrain 2010-07-23 13:43:40

+2

這不是一個論壇,而是一個Q和一個網站。最初我不確定MSVC++中代碼的有效性,但是在閱讀James的回答後,我意識到錯誤僅僅是一個intellisense錯誤,我的代碼完全有效。我可以自由地做我想做的任何事情。如果你不喜歡我的問題(或答案),那就不要發表你的回答/評論。它根本不需要。 「他們嘗試討論事物而不是幫助」主觀和增加的問題立即關閉。看起來你是這個網站的新手。 – 2010-07-26 02:22:04