2017-01-10 11 views
11

निम्न कोड विजुअल स्टूडियो 2008 में संकलित करता है लेकिन विजुअल स्टूडियो 2013 और बाद में विफल रहता है। बाइनरी '==':स्ट्रीम ऑपरेटर का मूल्यांकन >> बूलियन

std::string str("foo"); 
std::stringstream ss(str); 
float f = 0; 

if ((ss >> f) == false) 
    std::cout << "Parse error\n"; 

त्रुटि संदेश

त्रुटि C2678 है कोई ऑपरेटर पाया जो एक बाएं हाथ प्रकार के संकार्य लेता है 'std :: basic_istream>' (या वहाँ कोई स्वीकार्य रूपांतरण)

है और इस प्रकार सफलतापूर्वक बदलकर तय हो गई है:

if (!(ss >> f)) 
    std::cout << "Parse error\n"; 

मुझे यह अच्छी तरह से समझ में नहीं आ रहा है। मेरा सवाल यह है कि, ऑपरेटर या कास्ट या शायद ios झंडे शामिल हैं जो धारा को पहले स्थान पर बूलियन के रूप में मूल्यांकन करने की अनुमति देते हैं, और फिर operator== की कमी क्यों होती है?

उत्तर

16

सी ++ 11 के बाद से दो व्यवहार बदल गए।

  1. std::basic_ios::operator bool के व्यवहार बदल दिया है।

    operator void*() const;   (1) (until C++11) 
    explicit operator bool() const; (2) (since C++11) 
    

    नोट के बाद से सी ++ 11 operator bool()explicit के रूप में घोषित किया जाता है; लेकिन if ((ss >> f) == false), ss (यानी (ss >> f) का वापसी मूल्य) को bool (false से तुलना करने के लिए) में परिवर्तित करने की आवश्यकता है, जिसकी अनुमति नहीं है।

  2. शून्य सूचक स्थिरांक की परिभाषा बदल गई।

    सी ++ 11 operator void*() इस्तेमाल किया जा सकता से पहले और यह explicit (से पहले सी ++ 11 ऐसी कोई explicit user-defined conversion है) नहीं है, और इससे पहले कि सी ++ 11 the null pointer constant के रूप में परिभाषित किया गया है:

    एक अभिन्न निरंतर पूर्णांक प्रकार है कि (जब तक सी ++ 11) शून्य का मूल्यांकन

    जो false का मतलब है की अभिव्यक्ति rvalue एक अशक्त सूचक निरंतर रूप में इस्तेमाल किया जा सकता है। तो ss को void* पर स्पष्ट रूप से परिवर्तित किया जा सकता है और फिर false (शून्य सूचक के रूप में) की तुलना में किया जा सकता है।

    से सी ++ 11, नल पॉइंटर निरंतर रूप में परिभाषित किया गया है:

    एक पूर्णांक मान शून्य, या प्रकार का एक prvalue साथ शाब्दिक std::nullptr_t (के बाद से सी ++ 11)

    जबकि false फिर से नहीं है; यह integer literal नहीं है।

तो, क्योंकि इन दोनों में परिवर्तन की, if ((ss >> f) == false) में सी ++ 11 और बाद में काम नहीं करेगा।

दूसरी ओर, if (!(ss >> f)) ठीक काम करता है क्योंकि इसके लिए std::basic_ios::operator! (सी ++ 11 के पहले और बाद में) है।

bool operator!() const; 

रिटर्न true अगर जुड़े धारा पर कोई त्रुटि हुई है। विशेष रूप से, true देता है यदि rdstate() में खराब या विफलता सेट की गई है।

Btw: के बाद से सी ++ 11, यहां तक ​​कि std::basic_ios::operator! बिना, explicit operator bool() const भी अच्छी तरह से काम करता है if (!(ss >> f)), क्योंकि contextual conversion के संदर्भ में कर सकता है, explicit उपयोगकर्ता परिभाषित रूपांतरण माना जाता है; i.e. ss को operators ! के लिए प्रासंगिक रूप से bool में परिवर्तित किया जा सकता है।

+0

उल्लेख करने योग्य कुछ बात यह है कि 'अगर (foo) 'या' if (! Foo) '' ऑपरेटर बूल' को 'स्पष्ट 'चिह्नित किया गया है, तो' बूल 'ऑपरेटरों के स्पष्ट रूपांतरणों के बारे में कुछ अपवादों में से एक के कारण। उदाहरण [यहां] (http://coliru.stacked-crooked.com/a/e884a7adaf92a472)। मेरा मानना ​​है कि इसे ** प्रासंगिक रूपांतरण ** कहा जाता है, उदाहरण के लिए देखें। [यह ब्लॉग पोस्ट] (http://chris-sharpe.blogspot.ca/2013/07/contextually-converted-to-bool.html)। – vsoftco

+1

'NULL' एक मैक्रो है जो * ए * नल पॉइंटर स्थिरता तक फैलता है, न कि" शून्य "स्थिर, न ही" शून्य सूचक स्थिर "शब्द का पर्याय। –

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