2011-02-15 19 views
7

मैंने मानक पुस्तकालय के छोटे सीएलएजी कार्यान्वयन को पढ़ा और यह मुझे कॉन्स्ट और कॉन्स्टेक्स पर थोड़ा सा भ्रमित करता है।कंस्ट्रैक्स और कॉन्स का मिश्रण मिश्रण?

template<class _Tp, _Tp __v> 
struct integral_constant 
{ 
    static constexpr _Tp value = __v; 
}; 

template<class _Tp, _Tp __v> 
const _Tp integral_constant<_Tp, __v>::value; 

मुझे भ्रमित करने वाला यह है कि, यह कक्षा परिभाषा के अंदर constexpr का उपयोग कर रहा है और बाहर कांस्टेस्ट है। मेरा सवाल है, क्या यह अनुमति है? और किस स्थिति में कॉन्स्टेक्स और कॉन्टेक्सप्रैर का उपयोग मुझे अंतःक्रियात्मक रूप से किया जा सकता है? बेशक constexpr फ़ंक्शन कॉन्स्ट पर लागू नहीं हो सकते हैं, इसलिए मैं कॉन्स्ट डेटा और कॉन्टेक्सप्र डेटा के बारे में बात कर रहा हूं।

मैंने कुछ मानक ड्राफ्ट और http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf, में प्रस्ताव पढ़ा लेकिन यह मुझे और अधिक भ्रमित महसूस करता है। तो मैं कुछ और सवाल,

N2235 में, यह स्पष्ट रूप से कहा गया है कि, स्थिरांक डेटा एक संकलन समय स्थिरांक होने के लिए, निम्न उदाहरण देखने की गारंटी नहीं है,

struct S { 
static const int size; 
}; 
const int limit = 2 * S::size; // dynamic initialization 
const int S::size = 256; 

और constexpr है इस का समाधान माना जाता है है, तो कम से कम इस स्थिति के तहत, constexpr नीचे के रूप में अनुमति दी है नहीं,

struct S { 
static const int size; 
}; 
constexpr int limit = 2 * S::size; // shall be error in my understanding 
const int S::size = 256; 

हालांकि, सी ++ पढ़ने के बाद मानक प्रारूप N3225, मैं कहीं नहीं देख स्पष्ट रूप से कहा है कि ऊपर के उदाहरण त्रुटि हो जाएगा। विशेष रूप से, से 7.1.5/9,

एक constexpr एक वस्तु घोषणा में प्रयोग किया जाता विनिर्देशक स्थिरांक के रूप में वस्तु की घोषणा की। इस तरह के किसी ऑब्जेक्ट में शाब्दिक प्रकार होगा और इसे प्रारंभ किया जाएगा। यदि इसे कन्स्ट्रक्टर कॉल द्वारा प्रारंभ किया गया है, तो कन्स्ट्रक्टर कंस्ट्रैक्स कन्स्ट्रक्टर होगा और प्रत्येक कन्स्ट्रक्टर को तर्क निरंतर अभिव्यक्ति होगा। वह कॉल एक निरंतर अभिव्यक्ति (5.1 9) होगी। अन्यथा, प्रत्येक पूर्ण अभिव्यक्ति इसके प्रारंभकर्ता में दिखाई देती है निरंतर अभिव्यक्ति होगी।

इसलिए, यदि constexpr int limit = 2 * S :: आकार; अमान्य है, तो एस :: आकार निरंतर अभिव्यक्ति नहीं होना चाहिए, फिर 5.1 9 (निरंतर अभिव्यक्ति) से, मैं कहीं भी मानक निरंतर अभिव्यक्ति नहीं होने के लिए उपरोक्त उदाहरण में 2 * एस :: आकार को अस्वीकार करता हूं।

क्या कोई भी मुझे अनदेखा कर सकता है? आपका बहुत बहुत धन्यवाद।

उत्तर

3

एस :: आकार N3225 §5.19p2 के अनुसार एक निरंतर अभिव्यक्ति नहीं है:

सशर्त अभिव्यक्ति एक निरंतर अभिव्यक्ति है जब तक कि यह निम्न में से एक शामिल है ...

  • एक lvalue टू-रावल्यू रूपांतरण (4।1) जब तक यह
    • अभिन्न या गणन प्रकार का एक glvalue कि एक पूर्ववर्ती आरंभीकरण के साथ एक नॉन-वोलाटाइल स्थिरांक वस्तु को संदर्भित करता है, एक निरंतर अभिव्यक्ति के साथ प्रारंभ, या
    • [करने के लिए अन्य की स्थिति है कि नहीं लागू किया जाता है लागू]

नोट कैसे दूसरी बुलेट बिंदु मैं उद्धृत एक अभिन्न स्थिर डेटा सदस्य जो अपने आप में एक निरंतर अभिव्यक्ति भी एक निरंतर अभिव्यक्ति होने के लिए के साथ प्रारंभ है की अनुमति देता है, लेकिन अपने एस :: आकार अप्रारंभीकृत है ।

(साइड नोट:। क्योंकि है कि कैसे सी ++ व्याकरण काम करता है निरंतर-भाव सशर्त-भाव के रूप में परिभाषित कर रहे हैं)

आप सोच रहे हैं कि कैसे lvalue करने वाली rvalue रूपांतरण होता है, § देखना 5p9:

जब भी कोई glvalue अभिव्यक्ति एक ऑपरेटर के एक संकार्य कि कि संकार्य, lvalue करने वाली rvalue (4.1), सरणी-टू-सूचक (4.2), या समारोह करने के लिए एक prvalue उम्मीद के रूप में प्रकट -इंटर (4.3) अभिव्यक्ति को एक प्रसार में बदलने के लिए मानक रूपांतरण लागू होते हैं।

यह शायद 0xमानक पढ़ने के लिए एक अच्छा उदाहरण है, हालांकि 0x के लिए अभी तक और कुछ उपलब्ध नहीं है।

+0

हाय, धन्यवाद। मैंने इसे अनदेखा किया। हालांकि, हालांकि मुझे लगता है कि इंटरनेट पर कई लोगों ने यह कहा है, मुझे अभी भी पता नहीं चला कि मानक में कहां रखा गया है: असाइनमेंट ऑपरेटर सही पक्ष को रावल्यू होने की उम्मीद करता है, और बाइनरी अंकगणितीय ऑपरेटरों की अपेक्षा है कि उनके दोनों ऑपरेशन रावल्यू हों। – user534498

2

"हर पूर्ण अभिव्यक्ति प्रकट होगी, उसमें यह है प्रारंभकर्ता एक निरंतर अभिव्यक्ति बना रहेगा"

S::size एक निरंतर अभिव्यक्ति नहीं है, इसलिए यह एक निरंतर अभिव्यक्ति की प्रारंभ में प्रकट नहीं कर सकते हैं।

+1

मेरा प्रश्न वास्तव में है: क्यों एस :: आकार निरंतर अभिव्यक्ति नहीं है? मैंने कई बार 5.1 9 (निरंतर अभिव्यक्ति) पढ़ा और यह नहीं पाया कि यह इस मामले का उल्लेख करता है कि एस :: आकार निरंतर अभिव्यक्ति नहीं है। – user534498

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