2010-07-09 18 views
6

मैं निम्नलिखित कोडलैम्ब्डा अभिव्यक्ति (MSVC++ बनाम जी ++)

#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

तो है, वहाँ स्पष्ट रूप से स्थानीय लैम्ब्डा अभिव्यक्ति (std::for_each अंदर) के अंदर एक नया वेरिएबल बनाए बिना बाहरी-गुंजाइश चर sum उपयोग करने के लिए किसी भी अन्य तरीका है?

g++ 4.5 पर कोड ठीक संकलित करता है। मानक (n3000 मसौदा) इसके बारे में कुछ कहना है? (मैं सी के ++ एक प्रति नहीं है -? 0x (1x) वर्तमान में मानक)

+1

VS10 doees लैम्ब्डा कब्जा दायरे से संबंधित कुछ ज्ञात कीड़े, som सबसे अधिक संभावना जीसीसी सही इस मामले में है। – jalf

+0

बस हाल ही में एक मानक ड्राफ्ट डाउनलोड करें - Google पर "सी ++ मानक" की तलाश में आप इसके लिए एक लिंक देते हैं। यह देखने के लिए एक दिलचस्प सीखने का अनुभव है :) –

+2

ध्यान दें कि नवीनतम मसौदा एफसीडी, एन 30 9 2 है, जिसे आप [डब्लूजी 21 वेबसाइट से डाउनलोड कर सकते हैं] (http://www.open-std.org/jtc1/ sc22/wg21/दस्तावेज़/कागजात/2010/n3092.pdf) (** चेतावनी: 10.5 एमबी पीडीएफ **)। –

उत्तर

15

क्या आपने वास्तव में प्रश्न में कोड को संकलित करने का प्रयास किया है? विज़ुअल सी ++ 2010 कोड को स्वीकार करता है, जैसा कि (टिप्पणी हटा दी गई है, स्पष्ट रूप से), और त्रुटि के बिना कोड को सफलतापूर्वक संकलित करता है।

आप जो त्रुटि "देख रहे हैं" एक संकलन त्रुटि नहीं है, लेकिन एक IntelliSense त्रुटि है। IntelliSense त्रुटि जांच बहुत सारे झूठे सकारात्मक परिणामों में है (मैंने पिछले कुछ महीनों में माइक्रोसॉफ्ट कनेक्ट पर कई बग की सूचना दी है); इस मामले में, IntelliSense गलत तरीके से कह रहा है कि यह एक त्रुटि है जब यह नहीं है।

आपके पास दो विकल्प हैं: आप IntelliSense झूठी सकारात्मकताओं को अनदेखा कर सकते हैं या आप IntelliSense त्रुटि जांच अक्षम कर सकते हैं (त्रुटि सूची विंडो पर राइट-क्लिक करें और "IntelliSense त्रुटियां दिखाएं" अनचेक करें)।

किसी भी तरह से, इन IntelliSense त्रुटियों को किसी भी तरह से संकलन को सफल होने से रोक नहीं है।

0

मुझे लगता है कि आप स्पष्ट रूप से sum से अधिक बंद घोषित करने के लिए हो सकता है, इसलिए जैसे:

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

सामान्य तौर पर, आप अप्रत्यक्ष रूप से स्थानीय दायरे में चर पर कब्जा करने की अनुमति दी जानी चाहिए था रहे हैं, लेकिन केवल जब तक लैम्ब्डा की गारंटी है एक ही दायरे में चलाने के लिए। संभवतः क्योंकि आप अपने लैम्ब्डा को फ़ंक्शन वैर में असाइन कर रहे हैं और इसे बाद में निष्पादित कर रहे हैं (इसे सीधे चलाने के बजाए), एमएसवीसी समझने के लिए पर्याप्त स्मार्ट नहीं है कि यह स्थिति है - आखिरकार, आप संभावित रूप से l पास कर सकते हैं और इसे निष्पादित कर सकते हैं कुछ अन्य दायरे - इसलिए इसे स्पष्ट कैप्चर घोषणा की आवश्यकता है।

1

चाहे वीसी गलत या सही है, भले ही यह खराब शैली है कि आपके पास आपके (बाहरी) लैम्ब्डा के बाहर घोषित राशि है। चूंकि आप योग के मूल्य को वापस कर देते हैं, इसलिए लूप के अंदर बाहरी चर के मान को बदलने की आवश्यकता नहीं है। इसके बजाय, आप होना चाहिए:

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

यह भी हो सकता है कि नेस्टेड lambdas कुलपति भ्रमित कर रहे हैं। मैं कहूंगा कि यह घोंसला वाले लैम्बडास के लिए अधिक है, और कम पठनीय कोड बनाता है।

0

मुझे लगता है कि आपके पास एकमात्र समस्या है जो कि चींटी आकार लाल लहर के साथ है .... SINCE माइक्रोसॉफ्ट ने पहले संकलक जारी किया था और जल्द ही मानकों के शरीर ने नाम के लिए नियम बदल दिया था ... तो इंटेलिजेंस तक नहीं है तिथि ........

तो इस विचार के साथ छेड़छाड़ की कोशिश करें ..... बाबी ...

#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

मुझे पहले से ही जवाब मिल गया है और मेरी समस्या हल हो गई है। बीटीडब्ल्यू यहां कच्चे_पोइंटर का उपयोग करने की आवश्यकता नहीं है। यहां तक ​​कि योग के संदर्भ में समस्या हल हो गई होगी। बीटीडब्ल्यू आप 'इंटेलिसेंस त्रुटियों को दिखाएं' विकल्प बंद कर सकते हैं। मुझे उम्मीद है कि तुम यह जानते हो। हालांकि कोड तकनीकी रूप से सही है इसलिए मैंने इसे यहां भी उल्लेख किया है: http://stackoverflow.com/questions/3221812/sum-of-elements-in-a-vector/3221813#3221813 –

+0

यदि आपका कोड तकनीकी रूप से सही था I फोरम में ऐसी मूर्खतापूर्ण त्रुटियों को पोस्ट करने का कोई कारण नहीं मिला .... मुझे लगता है कि यदि आप एक अच्छे प्रोग्रामर हैं तो आप सार्वजनिक रूप से एक रोटी नहीं मारेंगे, इसलिए सभी कुत्ते उसके बाद दौड़ेंगे, (सदस्यों के लिए एक समानता यह मंच) ... वे मदद करने के बजाय चीजों पर चर्चा करने का प्रयास करते हैं ........ – perilbrain

+2

यह एक चर्चा मंच नहीं है लेकिन एक प्रश्नोत्तर साइट है। प्रारंभ में मैं एमएसवीसी ++ में कोड की वैधता के बारे में निश्चित नहीं था लेकिन जेम्स के जवाब पढ़ने के बाद मुझे एहसास हुआ कि त्रुटि केवल एक इंटेलिजेंस त्रुटि थी और मेरा कोड पूरी तरह से मान्य था। मैं जो कुछ भी चाहता हूं उसे करने के लिए स्वतंत्र हूं। यदि आपको मेरा प्रश्न पसंद नहीं है (या उत्तर) तो अपने उत्तर/टिप्पणियां पोस्ट न करें। यह बिल्कुल जरूरी नहीं है। 'वे उन प्रश्नों की मदद करने के बजाय चीजों पर चर्चा करने की कोशिश करते हैं जो विषयपरक हैं और संवर्द्धन तत्काल बंद हैं। ऐसा लगता है कि आप इस साइट के लिए नए हैं। –

संबंधित मुद्दे