c++ - क्या नल्ट्रेप्ल्सी झूठा है?




c++11 implicit-conversion (2)

जब एक बूलियन अभिव्यक्ति के रूप में इस्तेमाल किया जाता है या स्पष्ट रूप से या अंतर्निहित रूप से बूलियन में तब्दील हो जाता है, तो nullptr लगातार झूठ होता है? क्या यह कार्यान्वयन मानक में परिभाषित या निर्दिष्ट है?

मैंने परीक्षण करने के लिए कुछ कोड लिखे हैं, लेकिन यह निश्चित नहीं है कि यह पूरी तरह से इस संपत्ति का परीक्षण करता है या नहीं। मुझे कोई मौजूदा SO उत्तर नहीं मिला जो इस बारे में विशेष रूप से बात करता हो। cppreference इस बात का उल्लेख नहीं करता है कि मैं क्या देखता हूं।

if (nullptr) {
    ;
} else {
    std::cout << "Evaluates to false implicitly\n";
}

if (!nullptr) {
    std::cout << "Evaluates to false if operated on\n";
}

if (!(bool)(nullptr)) {
    std::cout << "Evaluates to false if explicitly cast to bool\n";
}

अपेक्षित और वास्तविक:

Evaluates to false implicitly
Evaluates to false if operated on
Evaluates to false if explicitly cast to bool

हां, लेकिन आपको इस तथ्य का उपयोग करने से बचना चाहिए।

false , या 0 की ओर संकेत करते false , C / C ++ कोडिंग में एक आम ट्रॉप है। मेरा सुझाव है कि आप इसका उपयोग करने से बचें । यदि आप अशक्तता की जाँच करना चाहते हैं, तो उपयोग करें:

if (x == nullptr) { /* ... */}

बजाय

if (!x) { /* ... */}

या

if (not x) { /* ... */}

दूसरा संस्करण पाठक के लिए एक और भ्रम पैदा करता है: x क्या है? क्या यह एक बूलियन है? एक सादा मूल्य (जैसे एक पूर्णांक)? एक सूचक? एक वैकल्पिक? यहां तक ​​कि अगर x का एक सार्थक नाम है, तो यह आपकी बहुत मदद नहीं करेगा: if (!network_connection) ... यह अभी भी एक पूर्णांक या बूलियन के लिए एक जटिल संरचना हो सकती है, तो यह एक संबंध होने का बूलियन संकेतक हो सकता है; , यह एक सूचक, एक मूल्य या एक वैकल्पिक हो सकता है। या कुछ और।

इसके अलावा, यह याद रखना कि nullptr झूठी का मूल्यांकन करता है एक और जानकारी है जिसे आपको अपने मस्तिष्क के पीछे स्टोर करने की आवश्यकता है जो आप पढ़ रहे कोड को ठीक से डिकोड कर सकते हैं। हम पुराने दिनों से या अन्य लोगों के कोड को पढ़ने से इसका उपयोग कर सकते हैं - लेकिन अगर हम नहीं थे, तो यह स्पष्ट नहीं होता कि nullptr उस तरह का व्यवहार करता है। एक अर्थ में, यह अन्य अस्पष्ट गारंटी के लिए भिन्न नहीं है, जैसे कि एक खाली std::string सूचकांक 0 पर मान 0 \0 std::string की गारंटी कैसे है । बस अपने कोड को इस सामान पर निर्भर न करें जब तक कि आपके पास बिल्कुल नहीं हो।

पुनश्च: इन दिनों अशक्त बिंदुओं के लिए वास्तव में बहुत कम उपयोग है। आप सूचक को कभी भी अशक्त होने के लिए मजबूर नहीं कर सकते हैं यदि उन्हें ज़रूरत नहीं है; आप संकेत के बजाय संदर्भ का उपयोग कर सकते हैं; और आप किसी T या "No T" को वापस करने के लिए std::optional<T> का उपयोग कर सकते हैं। शायद आप पूरी तरह से nullptr उल्लेख करने से बच सकते हैं।


C ++ 17 मानक (5.13.7 सूचक लीटर) के अनुसार

1 सूचक शाब्दिक शब्द nullptr है। यह प्रकार std :: nullptr_t का एक प्रकार है। [नोट: std :: nullptr_t एक अलग प्रकार है जो न तो पॉइंटर टाइप है और न ही पॉइंटर-टू-मेंबर टाइप; बल्कि, इस प्रकार का एक प्रहार एक अशक्त सूचक स्थिरांक है और इसे एक अशक्त सूचक मान या अशक्त सदस्य सूचक मान में परिवर्तित किया जा सकता है। 7.11 और 7.12 देखें। - अंतिम नोट]

और (7 मानक रूपांतरण)

4 कुछ भाषा निर्माणों को एक अभिव्यक्ति को बूलियन मान में बदलने की आवश्यकता होती है। इस तरह के संदर्भ में प्रदर्शित होने वाली एक अभिव्यक्ति ई को प्रासंगिक रूप से बूल में परिवर्तित करने के लिए कहा जाता है और इसे अच्छी तरह से गठित किया जाता है यदि और केवल अगर घोषणा बूल टी (ई); कुछ आविष्कार अस्थायी चर (11.6) के लिए अच्छी तरह से बनाया गया है

और अंत में (7.14 बुलियन रूपांतरण)

1 अंकगणित, अनकैप्ड एन्यूमरेशन, पॉइंटर या पॉइंटर-टू-मेंबर टाइप का एक प्रचलन टाइप बूल के प्रीलव्यू में बदला जा सकता है। शून्य मान, अशक्त सूचक मान या अशक्त सदस्य सूचक मान मिथ्या में परिवर्तित हो जाता है; किसी भी अन्य मान को सत्य में परिवर्तित किया जाता है। प्रत्यक्ष-आरंभीकरण (11.6) के लिए, प्रकार std :: nullptr_t का एक प्रकार टाइप बूल के एक प्रचलन में परिवर्तित किया जा सकता है; परिणामी मूल्य गलत है।

आप उदाहरण के लिए लिख सकते हैं

bool b( nullptr );

लेकिन आप लिख नहीं सकते हैं (हालांकि कुछ संकलक में इसके सापेक्ष बग है)

bool b = nullptr;

तो nullptr को संदर्भ-कथन जैसे चयन कथन में उदाहरण के लिए प्रकार बूल के ऑब्जेक्ट में रूपांतरित किया जा सकता है।

आइए उदाहरण के लिए विचार करें कि अपर संचालक ! जैसा कि अगर एक बयान में

if ( !nullptr ) { /*...*/ }

ऑपरेटर के विवरण के अनुसार (8.5.2.1 यूनिरी ऑपरेटर)

9 तार्किक निषेध संचालक का काम! प्रासंगिक रूप से बूल में परिवर्तित हो जाता है (क्लाज 7); इसका मान सत्य है यदि परिवर्तित ऑपरेंड गलत और गलत है। परिणाम का प्रकार बूल है

तो इस अभिव्यक्ति में nullptr एक पॉइंटर में परिवर्तित नहीं होता है। यह सीधे प्रासंगिक रूप से बूल में परिवर्तित हो जाता है।





nullptr