2010-07-11 7 views
8

सी ++ आईओ स्ट्रीम 'बेस क्लास std::basic_ios!fail() और operator!() को fail() वापस करने के लिए operator void*() को वापस करने के लिए परिभाषित करता है। इससे मुझे आश्चर्य होता है कि हमें operator!() क्यों चाहिए। निश्चित रूप से, !is भी operator void*() पर कॉल करके और इसके परिणाम को अस्वीकार कर काम करेगा।std :: basic_ios असामान्य तार्किक अस्वीकरण ऑपरेटर को अधिभार क्यों करता है?

क्या मुझे यहां कुछ याद आ रहा है या यह ऐतिहासिक कारणों से पूरी तरह से है कि std::basic_ios::operator!() परिभाषित किया गया है?

question on comp.lang.c++.moderated कोई जवाब नहीं मिला।

+0

ये 'basic_ios' के सदस्य कार्य हैं, न कि' ios_base'। –

+0

@ मार्सेलो: धन्यवाद, मैंने इसे ठीक किया है। – sbi

+0

@Neil: धन्यवाद, मैं उस बारे में भूल गया। वैसे भी, ऐसा लगता है कि आप या तो नहीं जानते? – sbi

उत्तर

5
के साथ वर्ष

(पढ़ें: के बाद नहीं लंबे cfront) सी ++ compilers, संकलक परोक्ष वस्तुओं पर टाइपकास्ट ऑपरेटरों कॉल करने के लिए जब जरूरत इसकी गारंटी नहीं किया गया था। यदि iostream में operator ! घोषित नहीं किया गया था, तो आप सभी मामलों में काम करने के लिए !cout की अपेक्षा नहीं कर सके। सी ++ 89 (या जो भी पूर्व-सी ++ 98 मानक कहा जाता था) बस अपरिभाषित क्षेत्र छोड़ दिया।

यही कारण है कि operator void*() ओवरलोड किया गया था, और operator int या operator bool नहीं था। (bool भी उस बिंदु पर मानक में अपना अलग प्रकार के रूप में मौजूद नहीं था।) मैं अपने प्रोफेसर याद मुझे उस if() कह, हुड के नीचे, उम्मीद सी ++ में एक void*, क्योंकि उस प्रकार एक "superset" प्रकार रिश्तेदार के रूप में कार्य कर सकता है उन अभिव्यक्ति परिणाम प्रकार है कि एक if बयान के लिए पारित किया जाएगा, लेकिन मैं नहीं मिला है इस कहीं से बताया है।

यह जीसीसी 2 के समय था, जब अधिकांश लोग टेम्पलेट्स या अपवादों का समर्थन नहीं करते थे, या यदि उन्होंने किया, तो उन्हें पूरी तरह से समर्थन नहीं मिला, इसलिए टेम्पलेट्स के साथ मेटाप्रोग्रामिंग सी ++ अभी भी एक सैद्धांतिक अभ्यास था और आपने सुनिश्चित किया जांच करने के लिए है कि operator new एक अशक्त सूचक वापस नहीं आए।

इससे मुझे कई सालों तक पागल हो गया।

स्ट्रॉस्ट्रप के सी ++ प्रोग्रामिंग भाषा, तृतीय संस्करण से एक दिलचस्प अंश। (1997), पृष्ठ 276:

IStream और ostream प्रकार एक रूपांतरण समारोह पर भरोसा करते हैं इस तरह के

while (cin >> x) cout << x; 

इनपुट आपरेशन CIN >> एक्स एक रिटर्न के रूप में बयान सक्षम करने के लिए आईएसट्रीम &। वह मान स्पष्ट रूप से cin की स्थिति को इंगित करने वाले मान में परिवर्तित हो गया है। मूल्य का परीक्षण और द्वारा किया जा सकता है। हालांकि, यह आमतौर पर एक प्रकार से दूसरे में एक अंतर्निहित रूपांतरण को परिभाषित करने का एक अच्छा विचार है जिससे रूपांतरण में जानकारी खो जाती है।

सी ++ में बहुत कुछ है जो लगातार सुन्दर या चालाक की जीत प्रतीत होता है। मैं एक बिट कोई फ़र्क नहीं पड़ेगा अगर सी ++ के रूप में ऊपर पाश को संभालने के लिए बहुत चालाक था:

while (!(cin >> x).fail()) cout << x; 

इस वजह है, जबकि अधिक वर्बोज़ और अधिक विराम चिह्न, एक शुरुआत प्रोग्रामर के लिए स्पष्ट है।

... असल में, इसके बारे में सोचने के लिए आओ, मुझे इनमें से किसी भी संरचना को पसंद नहीं है। इसे स्पेल करें:

for(;;) 
{ cin >> x; 
    if(!cin) 
     break; 
    cout << x; 
} 

मुझे यह बेहतर क्यों पसंद है? चूंकि यह संस्करण इसे स्पष्ट करता है कि कोड को विस्तारित करने के लिए, कहें, एक के बजाय एक समय में दो रीड को संभालें। उदाहरण के लिए, "मौजूदा कोड फ्लोट वैल्यू का अनुक्रम कॉपी करता है। हम चाहते हैं कि आप इसे बदल दें ताकि यह फ्लोट वैल्यू को जोड़ सके और उन्हें प्रति पंक्ति दो लिखें, क्योंकि अब हम जटिल संख्याओं का उपयोग कर रहे हैं।"

लेकिन मैं digress।

+0

तो यह एक और स्पष्टीकरण है जो मेरे संदेह की पुष्टि करता है कि 'ऑपरेटर!()' का उपयोग वर्तमान (तकनीकी) तकनीकी कारणों से नहीं किया जाता है। आपके उत्तर के दूसरे भाग के लिए: मैं धाराओं को एक बहुत ही प्राचीन डिजाइन पर विचार करता हूं। 'खराब()' जैसी चीजें 'खराब() 'के विपरीत नहीं हैं, _both_ buffer प्रबंधन करने वाले स्ट्रीम बफर और बाहरी डिवाइस से पढ़ने/पढ़ने के लिए, और, ठीक है, एक अनियंत्रित' ऑपरेटर!() 'शायद' आजकल बूस्ट की सहकर्मी समीक्षा कहें, द्वारा स्वीकार किया जाए। – sbi

+0

हां, यह एक विरासत की बात है, हालांकि तथ्य यह है कि यह स्पष्ट रूप से स्पष्ट है, कुछ अस्पष्टताओं को हल कर सकता है। (नहीं, मैं एक उदाहरण के बारे में नहीं सोच सकता।) और हां, धाराएं चालाक होने और राक्षस बनाने का एक अच्छा उदाहरण है। (शिफ्ट ऑपरेटरों को अधिभारित करना? वास्तव में ?! पर मुझे शुरू न करें ...) –

+0

व्यक्तिगत रूप से, मैं प्रस्तुति (स्वरूपण) और वितरण (बफरिंग, फ़ाइल I/O इत्यादि) को संभालने के साथ सी और सी ++ के जुनून से नाराज हूं।) एक ही समारोह में। वहां कितने कार्य हैं जिनके नाम 'printf' में समाप्त होते हैं? पाइथन का दृष्टिकोण बहुत अधिक है, फ़ॉर्मेटिंग और आउटपुट के साथ पूरी तरह अलग कार्यों के रूप में (सी ++ समतुल्य में 'std :: string std :: format (pattern, ...) 'फ़ंक्शन होगा)। –

1

MinGW, जो codeblocks के साथ भेज दिया है के कार्यान्वयन को देखते हुए मुझे इस कोड को दिखाता है:

operator void*() const 
    { return this->fail() ? 0 : const_cast<basic_ios*>(this); } 

    bool 
    operator!() const 
    { return this->fail(); } 

मुझे ऐसा लगता है, कि operator void*() const केवल सफलता की जांच करने के लिए और अधिक से अधिक उपयोग के लिए करना है। इसके शीर्ष पर यह एक कास्टिंग ऑपरेटर के रूप में भी कार्य करता है (हम this लौट रहे हैं)। अभी मैं अपने सिर एक छोटा सा, हम क्यों void* को this कास्ट करने के लिए चाहते हो सकता है खरोंच कर रहा हूँ। लेकिन बाकी बिल्कुल स्पष्ट है - अगर आपको एक गलत स्ट्रीम मिल गई है, तो आप भी शून्य वापस कर सकते हैं।

+3

+1 लेकिन मुझे लगता है कि यह केवल एक वैध सूचक (ठीक स्थिति में) लौटने के लिए एक तंत्र है और संभवतः कुछ जाल मूल्य नहीं है। –

+1

@Neil: हाँ, मुझे ऐसा भी लगता है। मानक 'ऑपरेटर शून्य *() '(27.4.4.3/1 में) के बारे में बताता है:" रिटर्न: यदि' असफल() 'तो एक शून्य सूचक, अन्यथा कुछ गैर-शून्य सूचक सफलता को इंगित करने के लिए कहते हैं।" यह सिर्फ एक सुरक्षित बूल लौटने वाला है! असफल() '। 'ऑपरेटर के बारे में!() 'यह कहता है (27.4.4.3/2 में):" रिटर्न: 'असफल() '।" – sbi

2

ठीक है, यहां सूख आ रहा है, मैं गया और asked on comp.lang.c++.moderated

सबसे पहले, परिणाम बस के रूप में बुरा वे यहाँ किया गया है के रूप में थे, लेकिन अंत में Daniel Krügler's answer मेरी संदेह में सहमति जताई वहाँ operator!() के लिए कोई तकनीकी कारण हैं कि:

मुझे बताया गया है, कि इस अतिरिक्त घोषणा "सही" मामले के बीच समरूपता पर जोर करने के लिए जोड़ा गया था और यह निषेध है, बस पाठक, ज्यादा कुछ नहीं के लिए एक गाइड के रूप में। निष्पक्ष होना करने के लिए, मुहावरा

operator void* 

तुरंत स्पष्ट नहीं बल्कि इस समय नए और इस कटौती जो वाक्य रचना समर्थन इस सुविधा द्वारा प्रदान की जाती दिया था नहीं है। इसके अलावा ऐसा करने का कोई और तकनीकी कारण नहीं था। [...]

+3

डैनियल क्रुगलर आसानी से ऑनलाइन फ़ोरम में सबसे उपयोगी लोगों में से एक है। अगर हम केवल स्टैक ओवरफ्लो पर पार्टी में शामिल होने के लिए उसे प्राप्त कर सकते हैं ... –

+1

@ जेम्स: उस पर +1। वह litb ++ की तरह है (कोई अपराध नहीं, जोहान्स। <3) – GManNickG

+0

@ जेम्स, @GMan: मैं वास्तव में 90 के दशक में स्पैन्गेनबर्ग होने का आखिरी नाम याद रखने के लिए पुराना हूं। ': -/ – sbi

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