c++ क्यों कर सकते हैं चार कास्ट*कास्ट &="हैलो" संकलन?




reference const (2)

ऊब के लिए कुछ अतिरिक्त phrasing, @StoryTeller द्वारा शानदार जवाब पढ़ने के बाद, क्योंकि मुझे इस बारे में एक अलग विचार प्रक्रिया से गुजरना पड़ा।

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

const char* const & a = "hello";

और यहाँ नहीं:

const char*& a = "hello";

इस 2 const अर्थ है कि इस मामले में एक संकेतक, इस मामले में एक संकेतक के रूप में संदर्भित किया जा रहा है , क्योंकि यह इस संदर्भ का उपयोग करके संशोधित नहीं किया जा सकता है।

इसलिए, क्योंकि इस स्ट्रिंग शाब्दिक का प्रकार const char[6] (और उदाहरण के लिए const char * नहीं), दूसरी पंक्ति में const char* टाइप करने के लिए हमारा lvalue संदर्भ इसे बांध नहीं सकता है - लेकिन पहली पंक्ति में संदर्भ , const char* const टाइप करने के लिए एक संदर्भ जा रहा है। क्यूं कर? संदर्भ आरंभीकरण के नियमों के कारण:

(5) "cv1 T1" टाइप करने के लिए एक संदर्भ प्रकार "cv2 T2" की अभिव्यक्ति द्वारा आरंभ किया गया है:

  • (५.१) यदि संदर्भ एक लैवल्यू रेफरेंस और इनिशियलाइज़र एक्सप्रेशन है

    • (५.१.१) एक अंतराल है (लेकिन बिट-फील्ड नहीं है), और "cv1 T1" "cv2 T2", [...] के साथ संदर्भ-संगत है
    • (5.1.2) का एक वर्ग प्रकार होता है (जैसे, T2 एक वर्ग प्रकार है) [...]

दोनों अभिव्यक्तियाँ lvalue s हैं, लेकिन हमारा "cv1 T1" हमारे "cv2 T2" के साथ reference-compatible नहीं है और "T2" एक वर्ग प्रकार नहीं है।

  • (५.२) अन्यथा, यदि संदर्भ एक प्रकार का एक अंतराल संदर्भ है, जो कांस्टेबल-योग्य नहीं है या अस्थिर-योग्य है, तो प्रोग्राम बीमार है।

संदर्भ वास्तव में कॉन्स्टेबल-योग्य नहीं है: हमारा "टी 1" const char* , जो कि कॉन्स्टेंट पॉइंटर है, जो कि कॉन्स्ट पॉइंटर के विपरीत है। यहां वास्तविक प्रकार एक सूचक प्रकार है, इसलिए यही मायने रखता है।

दूसरी पंक्ति के लिए क्लैंग त्रुटि, जिसे ध्यान में रखकर पढ़ा जाता है, हमें ठीक यही बताता है:

error: non-const lvalue reference to type 'const char *' cannot bind to a value of unrelated type 'const char [6]'
    const char*& a = "hello";
                 ^    ~~~~~~~

नॉन- कॉन्स्टल लैवल्यू रेफरेंस होने के बारे में हिस्सा बिल्कुल .25.2 है - हमारे मामले में लैवल्यू कॉन्स्टेंट है जो कॉन्स्टेंट है, लेकिन खुद कांस्ट नहीं है! पहली पंक्ति के विपरीत। असंबंधित प्रकार के लिए बाध्य करने के बारे में हिस्सा बिल्कुल .15.1 है - हमारा const char* चर const char* आरएचएस कास्ट const char[6] , या कास्ट const char* कास्ट के बाद सरणी पॉइंटर रूपांतरण के अनुरूप नहीं है।

इस सटीक कारण, या इसके अभाव के कारण, यह त्रुटि मुक्त संकलन कर सकता है:

char* const & a = "hello";

आईएसओ सी ++ 11 को एक तरफ चेतावनी देते हुए, एक संकलक इसे एक पास देता है (ऐसा नहीं है कि यह होना चाहिए, क्योंकि स्ट्रिंग शाब्दिक एक 'कास्ट चार 6 ' है और हमें इस पहले const छोड़ना नहीं चाहिए), क्योंकि संदर्भ अब साथ है अपनी वस्तु, सूचक के संबंध में।

एक और दिलचस्प बात यह है कि एक rvalue रेफरेंस const char* && a (कोई भी "2nd const ") अस्थाई पॉइंटर को नहीं बाँध सकता है जो स्ट्रिंग शाब्दिक से भौतिक है, जैसा कि @StoryTeller ने खुद को प्रदान किया है। ऐसा क्यों है? 6 के नियमों के कारण 6

"एनटी की सरणी" या "टी की अज्ञात सीमा के सरणी" के प्रकार का एक अंतराल या अंतराल को "पॉइंटर टू टी" के प्रकार से बदला जा सकता है

यहाँ पर const या अन्य cv- क्वालिफिकेशन योग्‍यता का कोई उल्‍लेख नहीं है, लेकिन यह केवल तभी तक खड़ा है जब तक हम एक rvalue ref को इनिशियलाइज़ कर रहे हैं।

https://code.i-harness.com

मैं एक किताब से एक कोड स्निपेट पढ़ रहा हूं और यह पाता हूं:

const char* const & a = "hello"; //can compile 
const char*& a = "hello"; //cannot

मुझे केवल इतना पता है कि एक संदर्भ को शुरू करते समय, सूचक रूपांतरण के लिए सरणी नहीं होगी।

const char* const & , एक const pointer संदर्भ, पॉइंटर const char को इंगित करता है।

const char*& , pointer संदर्भ, सूचक const char का संकेत देता है।

तो क्यों एक अतिरिक्त const जोड़ रहा है, यह दर्शाता है कि सूचक एक const , इसे संकलित करने की अनुमति दें?


यह अनिवार्य रूप से इस सूत्र का पालन कर रहा है

T const & a = something_convertible_to_T;

जहां T const char* । पहले मामले में, एक अस्थायी सूचक को भौतिक किया जा सकता है, शाब्दिक के पते को सौंपा जा सकता है, और फिर खुद को संदर्भ के लिए बाध्य किया जा सकता है। दूसरे मामले में, चूंकि लैवल्यू रेफरेंस में कोई कमी नहीं है, इसलिए ऐसा नहीं हो सकता। उसी का एक और उदाहरण

const char* && a = "hello"; // rvalue ref makes a no into a yes.

अब अस्थायी पॉइंटर एक रेवल्यू रेफरेंस के लिए बाध्य है।







language-lawyer