2016-08-16 27 views
29

मैं सी ++ कि का कहना है कि अगर मैं का उपयोग >> ऑपरेटर यह ऑपरेटर की बाईं ओर ऑब्जेक्ट तो इस उदाहरण में पर एक किताब पढ़ रहा हूँstd :: cin एक ही समय में एक बूल और खुद को कैसे वापस कर सकता है?

std::cin >> value1; 

कोड लौटाता है std::cin

लेकिन अगर मैं ऐसा करते हैं

while(std::cin >> value1) 

मेरे कोड पाश में होगा एक std::cin त्रुटि नहीं होने तक, तो इसका मतलब यह होगा कि ऑपरेटर की ओर से एक bool कि सच है जब std::cin में विफल नहीं हुआ और झूठे जब है std::cin विफल रहता है।

यह कौन सा है?

+18

'std :: cin' में एक रूपांतरण ऑपरेटर भी 'बूल' है जिसका उपयोग इस स्थिति में किया जाता है। –

+5

@ πάνταῥεῖ टिप्पणियां टिप्पणियों के लिए हैं, जवाब नहीं। – Mego

उत्तर

46

[...] तो इसका मतलब यह होगा कि ऑपरेटर एक bool रिटर्न [...]

नहीं, यह रिटर्न std::cin (संदर्भ द्वारा)। कारण while(std::cin >> value); काम करता है क्योंकि std::istream (जो std::cin का प्रकार है) में conversion operator है।

एक रूपांतरण ऑपरेटर मूल रूप से एक वर्ग को अंतर्निहित रूप से अनुमति देता है (यदि इसे किसी दिए गए प्रकार में परिवर्तित करने के लिए explicit चिह्नित नहीं किया गया है)। इस मामले में, std::istream अपनी operator bool को वापस करने के लिए परिभाषित करता है कि कोई त्रुटि (आमतौर पर failbit) हुई है;

[std::ios_base::operator bool()]

रिटर्न true यदि धारा कोई त्रुटि नहीं है और मैं/हे कार्यों के लिए तैयार है। विशेष रूप से, !fail() देता है।


explicit operator bool() const; 

नोट से भले ही ऑपरेटर explicit है (जो if (std::cin); जैसी निहित रूपांतरण की अनुमति नहीं होना चाहिए), क्वालीफायर जब एक संदर्भ है कि एक bool की आवश्यकता में इस्तेमाल किया नजरअंदाज कर दिया है, whileif की तरह, लूप और for लूप। हालांकि, अपवाद हैं, नियम नहीं।

यहाँ एक उदाहरण है:

if (std::cin >> value); //OK, a 'std::istream' can be converted into a 'bool', which 
         //therefore happens implicitly, without the need to cast it: 

if (static_cast<bool>(std::cin >> value)); //Unnecessary 

bool b = std::cin >> value; //Error!! 'operator bool' is marked explicit (see above), so 
          //we have to call it explicitly: 

bool b = static_cast<bool>(std::cin >> value); //OK, 'operator bool' is called explicitly 
+0

यह ओपी के लिए कम भ्रमित हो सकता है यदि आप इंगित करते हैं कि एक साधारण 'शून्य * पीआरटी = न्यूल: अगर (पीआरटी) 'भी काम करता है (जिसके साथ वह निश्चित रूप से परिचित है), क्योंकि यह _convertibility_' bool' है जो महत्वपूर्ण है मूल रूप से 'बूल' प्रकार वाली वास्तविक अभिव्यक्ति के बजाय। –

+1

@ लाइटनेसरेसेसिन ऑर्बिट अच्छा विचार :) लेकिन यह * * शून्य * के बिना बेहतर हो सकता है, इसे टालना चाहिए। – Rakete1111

+2

मुझे लगता है कि नियम से अपवादों के अतिरिक्त यह 'बूल अच्छा = std :: cin;' जैसे अपवाद को जोड़ने के लिए उपयोगी होगा, जो सही रूप से संकलित नहीं होता है। – Ruslan

21

std::istream (वर्ग जो std::cin की एक वस्तु है) के बाद सदस्य समारोह है: अगर वस्तु एक त्रुटि में है

explicit operator bool() const; 

यह झूठी रिटर्न राज्य, और अन्यथा सच है। यही कारण है कि while(std::cin >> value1) निर्माण कार्य करता है।

operator void*() const; 

जो एक नल पॉइंटर लौटे अगर वस्तु एक त्रुटि स्थिति में था, एक ही उद्देश्य की सेवा: सी ++ 11 से पहले, यह इस गैर स्पष्ट फ़ंक्शन बजाय था।

3

धाराओं पर संचालन धारा के संदर्भ को वापस कर देता है।

तो, bool नहीं।

आप एक ही कारण है कि आप यह कर सकते हैं कि के लिए एक if हालत में परिणाम छड़ी कर सकते हैं: उस बात के लिए

void* ptr = foo(); 
if (ptr) { /*...*/ } 

और,, इस:

int x = foo(); 
if (x) { /*...*/ } 

दोनों ptr और x यहाँ इस स्थिति में उपयोग के लिए को bool में परिवर्तित किया जा सकता है। std::cin के मामले में, रूपांतरण operator bool() द्वारा std::ostream कक्षा के भीतर प्राप्त किया गया है जो स्पष्ट रूप से (पंच इरादा) इस सटीक कार्य के लिए जोड़ा गया था।

1

std::cin

(जो सिर्फ std::basic_istream<char> के typedef है) आप different overloaded operator>> for basic_istream देखते हैं, उन सभी को basic_istream के लिए एक संदर्भ लौट रहे हैं प्रकार std::istream की है। इसलिए एक बात साफ हो गई है कि operator>> यहां bool वापस नहीं लौटाता है, बल्कि इसके बजाय, यह "std::cin" स्वयं लौटाता है। आपको operator>> कोई bool मान वापस नहीं देखेगा।

तो सवाल अब है, यह std::basic_istream से bool में कैसे परिवर्तित करता है?
उत्तर है: इस उद्देश्य के लिए रूपांतरण ऑपरेटर कहा जा रहा है।

std::basic_istream अपनी मूल std::basic_ios

explicit operator bool() const; 

यह संभव bool करने के लिए एक std::basic_istream वस्तु कन्वर्ट करने के लिए बनाता है, जो एक operator bool() इनहेरिट करती है। कोई आसानी से आश्चर्यचकित कर सकता है कि इसे explicit चिह्नित किया गया है (why is it marked explicit देखें) और फिर भी यह में if या while में निहित रूप से परिवर्तित हो गया है।

इस प्रश्न का उत्तर यह है कि if या while स्पष्ट रूप से "स्पष्ट रूप से" स्पष्ट रूपांतरण का उपयोग करें। (this answer by @R. Martinho Fernandes देखें)। तो if, while और for उन स्थानों में से एक हैं जहां यह "प्रासंगिक रूपांतरण" bool पर स्पष्ट रूप से होता है।

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