2011-09-15 17 views
17

यह मान्य है, क्योंकि constexpr अभिव्यक्ति को "शाब्दिक प्रकार का एक ग्लैवल्यू" मानने की अनुमति है जो कॉन्स्टेक्स के साथ परिभाषित एक गैर-अस्थिर वस्तु को संदर्भित करता है, या जो इस तरह के ऑब्जेक्ट के उप-ऑब्जेक्ट को संदर्भित करता है "(§ 5.19/2):एक स्ट्रिंग अक्षर को लगातार अभिव्यक्ति में सब्सक्राइब किया जा सकता है?

constexpr char str[] = "hello, world"; 
constexpr char e = str[1]; 

हालांकि, यह प्रतीत होता है कि स्ट्रिंग शाब्दिक इस विवरण फिट नहीं है:

:

constexpr char e = "hello, world"[1]; // error: literal is not constexpr 

2.14.5/8 स्ट्रिंग शाब्दिक के प्रकार का वर्णन

सामान्य स्ट्रिंग अक्षर और यूटीएफ -8 स्ट्रिंग अक्षर को भी संकीर्ण स्ट्रिंग अक्षर के रूप में जाना जाता है। एक संकीर्ण स्ट्रिंग शाब्दिक में "एन कॉन्स्ट चार का सरणी" टाइप होता है, जहां n नीचे परिभाषित स्ट्रिंग का आकार होता है, और इसमें स्थिर भंडारण अवधि होती है।

यह (, 5.19/2 सही ऊपर स्निपेट के बाद), प्रतीत होता है कि इस प्रकार का ऑब्जेक्ट अनुक्रमित किया जा सकता है अगर केवल यह अस्थायी और स्थिर भंडारण अवधि के नहीं थे:

[constexpr की अनुमति देता है lvalue करने वाली rvalue] ... शाब्दिक प्रकार का एक glvalue कि एक गैर अस्थिर अस्थायी वस्तु जिसका जीवन समाप्त नहीं किया गया है, एक निरंतर अभिव्यक्ति

साथ प्रारंभ करने के लिए संदर्भित करता है के रूपांतरण इस के lvalue लेने के बाद से विशेष रूप से अजीब है एक अस्थायी वस्तु आमतौर पर "सी गरम करना।" मुझे लगता है कि इस नियम इस तरह के

constexpr char get_1(char const (&str)[ 6 ]) 
    { return str[ 1 ]; } 

constexpr char i = get_1({ 'y', 'i', 'k', 'e', 's', '\0' }); // OK 
constexpr char e = get_1("hello"); // error: string literal not temporary 

क्या इसके लायक है के लिए में, जीसीसी 4.7 get_1("hello") स्वीकार करता है के रूप में संदर्भ प्रकार के तर्कों, कार्य करने के लिए लागू होता है, लेकिन "hello"[1] को खारिज कर दिया क्योंकि "का मान '._0' एक निरंतर में प्रयोग करने योग्य नहीं है अभिव्यक्ति "... अभी तक "hello"[1] एक केस लेबल या सरणी बाध्य के रूप में स्वीकार्य है।

मैं यहां कुछ मानक बाल बांट रहा हूं ... क्या विश्लेषण सही है, और क्या इस सुविधा के लिए कुछ डिज़ाइन इरादा था?

संपादित करें: ओह ... इसके लिए कुछ प्रेरणा है। ऐसा लगता है कि इस तरह की अभिव्यक्ति प्रीप्रोसेसर में लुकअप टेबल का उपयोग करने का एकमात्र तरीका है। उदाहरण के लिए, इस जो जब तक SOME_INTEGER_FLAG 1 या 5 नजरअंदाज कर दिया है कोड का एक खंड परिचय है, और एक नैदानिक ​​का कारण बनता है, तो अधिक से अधिक 6 से:

#if "\0\1\0\0\0\1"[ SOME_INTEGER_FLAG ] 

इस निर्माण के लिए सी ++ 11 नए होगा।

उत्तर

6

इरादा यह है कि यह काम करता है और अनुच्छेद जो बताते हैं कि जब रावल्यू रूपांतरण के लिए एक लाभा वैध है be amended with a note जो बताता है कि एक अंतराल जो स्ट्रिंग अक्षर के उप-प्रोजेक्ट को संदर्भित करता है, निरंतर अभिव्यक्ति के साथ प्रारंभिक पूर्णांक ऑब्जेक्ट होता है (जिसे सी ++ 11 ड्राफ्ट के बाद एक स्वीकृत मामलों में से एक के रूप में वर्णित किया गया है)।

प्रीप्रोसेसर के भीतर उपयोग के बारे में आपकी टिप्पणी दिलचस्प लगती है लेकिन मुझे यकीन है कि यह काम करने का इरादा है या नहीं। मैं इस बारे में पहली बार सुनता हूं।

+0

मुझे लगता है कि नोट गैर-मानक हैं, क्यों ध्यान दें? –

+2

मुझे लगता है कि बिंदु यह है कि शब्द पहले से ही इस व्याख्या का समर्थन करता है, यह सिर्फ इतना स्पष्ट नहीं है और संदेह थे; इसलिए इस विशेष कोने के मामले की व्याख्या करने में मदद करने के लिए एक नोट। वैसे भी, यह कमाल की खबर है। –

+1

दिलचस्प! चूंकि मामला 2 5.1 9 के तहत लाइवल-टू-रावल्यू रूपांतरण उप-प्रोजेक्ट्स को संदर्भित करता है, इसलिए मुझे यकीन नहीं था कि केस 1 एरे के सदस्यों पर लागू होता है या नहीं। तो, उन मामलों के बीच बहुत अधिक ओवरलैप है। प्रीप्रोसेसर चाल के लिए ... '# यदि निरंतर अभिव्यक्तियों को स्वच्छ करने के लिए' 0' पर squishing पहचानकर्ताओं पर निर्भर करता है। फिर 16.1/4 लागू होता है, "परिणामी टोकन में नियंत्रण निरंतर अभिव्यक्ति होती है जिसका मूल्यांकन गणित का उपयोग करके 5.1 9 के नियमों के अनुसार किया जाता है जिसमें कम से कम 18.3 में निर्दिष्ट श्रेणियां होती हैं।" इसके बारे में सोचने के लिए आओ, एक यूडी-प्रत्यय स्ट्रिंग '0' रूपांतरण के प्रति प्रतिरोधी है! उह ओह! – Potatoswatter

1

#if के बारे में आपके प्रश्न के बारे में, यह मानदंडों के सेट को बढ़ाने के लिए मानक समिति का इरादा नहीं था जिसे प्रीप्रोसेसर में उपयोग किया जा सकता है, और वर्तमान शब्द को दोष माना जाता है। कोना डब्लूजी 21 मेलिंग के बाद इसे कोर इश्यू 1436 के रूप में सूचीबद्ध किया जाएगा। इसे हमारे ध्यान में लाने के लिए धन्यवाद!

+0

[डीआर 366] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#366) §5.1 9 के संदर्भ में सशर्त प्रीप्रोकैसिंग समस्या को शामिल करता है। जाहिर है मानक के कामकाजी मसौदे को पैच किया गया था लेकिन बाद में बदलाव से फिक्स ओवरराइट किया गया था। शायद नया फिक्स §16 में है, क्योंकि वर्तमान इरादा शक्तिशाली निरंतर अभिव्यक्तियों के लिए है। – Potatoswatter