2012-01-22 6 views
16

शायद मैं जंगली हो रहा हूं (हाल ही में पाइथन में लिख रहा हूं)।यदि स्थिति है तो एक चर घोषित करने में क्या गलत है?

यह संकलित क्यों नहीं करता है? i की

if ((int i=f()) == 0) 
int i=f() मैं एक मिल के आसपास () बिना

, और अधिक उचित त्रुटि बूलियन नहीं किया जा रहा है। लेकिन यही कारण है कि मैं पहली जगह में कोष्ठक चाहता था!

मेरा अनुमान है कि कोष्ठक का उपयोग करके इसे अभिव्यक्ति में बनाया जाता है, और अभिव्यक्ति में घोषणा विवरणों की अनुमति नहीं है। ऐसा है क्या? और यदि हां, तो यह सी ++ के वाक्यविन्यास quirks में से एक है?

Btw, मैं वास्तव में यह करने के लिए कोशिश कर रहा था:

if ((Mymap::iterator it = m.find(name)) != m.end()) 
    return it->second; 
+1

क्या गलत है? सब कुछ –

+5

@VJovic - यदि आप इस तरह के विस्तृत, उपयोगी उत्तरों से अपना प्रतिष्ठा स्कोर प्राप्त करते हैं तो मैं भटक जाता हूं;) – davka

+0

नहीं, मैं नकारात्मक हो जाऊंगा;) लेकिन गंभीरता से, किसी भी सामान्य कोडिंग मानकों को ऐसे अस्पष्ट कोड को रोक दिया जाता है। –

उत्तर

37

आप सी में if बयान में एक चर घोषणा कर सकते हैं ++ लेकिन यह प्रत्यक्ष प्रारंभ के साथ इस्तेमाल किया जा के लिए प्रतिबंधित है और यह एक बूलियन मान में बदलने की जरूरत है:

if (int i = f()) { ... } 

सी ++ जो कुछ भी कर सकता है नहीं है "घोषणा अभिव्यक्ति" के रूप में वर्णित किया जाना चाहिए, यानी [उप-] अभिव्यक्तियों को एक चर घोषित करना।

वास्तव में, मैं बस खंड मानक में देखा और आरंभीकरण के दोनों रूपों 6.4 के अनुसार समर्थन कर रहे [stmt.select] अनुच्छेद 1:

... 
condition: 
    expression 
    attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause 
    attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list 
... 

है यही कारण है कि, यह भी लिखने के लिए संभव हो सकता है कर रहा है :

if (int i{f()}) { ... } 

जाहिर है, यह केवल सी ++ 2011 में काम करता है क्योंकि सी ++ 2003 में ब्रेस-प्रारंभिकता नहीं है।

+0

मुझे नहीं लगता कि आपका आखिरी उदाहरण कानूनी है। आप केवल 'अगर (int i {f()}) {/*...*/} 'या' if (int i = f()) {/*...*/} 'कर सकते हैं। _braced-init-list_ में ब्रेसिज़ शामिल होना चाहिए। (_braced-init-list_ "{_initializer-list_, OPT}" या "{}" है)। –

+0

@ चार्ल्सबैली: हाँ, आप सही हैं: मैंने किसी भी तरह से "ब्रेस्ड-इनिट-लिस्ट" का अर्थ गलत (...) किया है। मैं इसे ठीक कर दूंगा। –

+0

धन्यवाद, उचित लगता है, और नीचे @ इल्या का उत्तर कुछ तर्क – davka

20

वहाँ गुंजाइश के साथ एक समस्या है।

निम्नलिखित कोड पर विचार करें:

if ((int a = foo1()) || (int b = foo2())) 
{ 
    bar(b); 
} 

ख ब्लॉक के अंदर घोषित है? क्या होगा यदि foo1() सच है?

+0

यह उल्लेख करना भूल गया कि मैं' टी लगता है कि यह एक दायरा मुद्दा है क्योंकि '()' AFAIK गुंजाइश नहीं बना रहा है। क्या मैं गलत हूँ? – davka

+3

@ सोपबॉक्स लेकिन क्या होगा यदि foo1 1 लौटाता है और शॉर्ट-सर्किट मूल्यांकन (जिसे मुझे पता है) द्वारा 'गारंटी 'की गारंटी दी जाती है? – lccarrasco

+0

बिल्कुल - आप वैरिएबल को घोषित करने का प्रस्ताव नहीं दे सकते() जब तक आप स्कोप समस्या को संबोधित नहीं करते; सी ++ में चर के पास ऐसा दायरा होता है जब उनकी घोषणा 'निष्पादित' होती है, जो इस स्थिति में कभी नहीं हो सकती है। – greggo

4

आप एक कथन (या के लिए या दौरान) में एक चर घोषित कर सकते हैं, लेकिन केवल बाहरी कोष्ठक ब्लॉक में और इसे बूल में परिवर्तित करने में सक्षम होना चाहिए।

आपका अनुमान मूल रूप से सही है, यह अनुमति नहीं है है, क्योंकि

(int i = 42;) 

आरंभीकरण के साथ एक मान्य घोषणा नहीं है।

आप एक अतिरिक्त पंक्ति की जरूरत है,

Mymap::iterator it; 
if ((it = m.find(name)) != m.end()) 
    return it->second; 

लेकिन फिर इसे लिखने के लिए

Mymap::iterator it = m.find(name); 
if (it != m.end()) 
    return it->second; 

आप if के बाद return लाइन डाल सकते हैं बेहतर है, यदि आप वास्तव में इस लाइन वापस चाहते हैं कम से कम, मेरे लिए यह पठनीयता को नुकसान नहीं पहुंचाता है, लेकिन अन्य लोग इसे अलग देख सकते हैं।

आप सच में, सच पुनरावर्तक घोषित करने और एक if हालत में bool के रूप में इसका उपयोग करना चाहते हैं, तो आप

if (struct { int it; operator bool() { return it != m.end; } } s = { m.find(name) }) 
    return s.it->second; 

कर सकता है, लेकिन मैं इस पर विचार करेंगे हानिकारक ;-)

0

यह सच है कि आप

if ((int i=f()) == 0) 

नहीं लिख सकते हैं, लेकिन आप पूरी तरह से लिख सकते हैं

if (int i=f()) 

तो तुम जैसे

if (int i=1 && (i=f()) == 0) 

i 0 के अलावा अन्य किसी भी मूल्य के साथ प्रारंभ किया जाना चाहिए एक बयान में दोनों कार्रवाई करने && ऑपरेटर का उपयोग कर सकते हैं, और यह पहली शर्त होना चाहिए, अगर आपके संकलक बाईं लागू होता है सही मूल्यांकन।

लेकिन दुर्भाग्यवश, यह आपके दूसरे उदाहरण के रूप में इटरेटर के मामले में लागू नहीं है।

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