2012-06-09 19 views
11

मुझे कुछ मौलिक याद आ रही है। मैं संकलन समय पर कॉन्स सरणी सदस्यों का उपयोग करने की कोशिश कर रहा हूं।संकलन-समय सरणी स्थिरांक

const int list[3] = { 2, 5, 7 }; 
const int a = list[2]; // this doesn't error? 

template<int N1, int N2> 
struct tmax { 
    enum { value = ((N1 > N2) ? N1 : N2) }; 
}; 

const int b = tmax<2,4>::value; 
const int c = tmax<list[0],list[1]>::value; // error is here 

int main() 
{ 
    return 0; 
} 

त्रुटियाँ:

prog.cpp:10:24: error: 'list' cannot appear in a constant-expression 
prog.cpp:10:30: error: an array reference cannot appear in a constant-expression 

यहाँ relevent IDEOne link

तो क्यों यह काम नहीं करता है? मैं क्या खो रहा हूँ? मुझे अलग-अलग क्या करना चाहिए?

उत्तर

9

सिर्फ इसलिए कि कोई ऑब्जेक्ट const का मतलब यह नहीं है कि यह संकलन समय निरंतर अभिव्यक्ति है।

constexpr int list[3] = { 2, 5, 7 }; 

template<int N1, int N2> 
struct tmax { 
    enum { value = ((N1 > N2) ? N1 : N2) }; 
}; 

const int b = tmax<2,4>::value; 
const int c = tmax<list[0],list[1]>::value; // works fine now 

क्यों यह काम करता है के लिए के रूप में::

const int a = list[2]; // this doesn't error? 

एक const चर आरंभ एक निरंतर अभिव्यक्ति की आवश्यकता नहीं है:

int foo(int n) { 
    const int a = n; // initializing const var with a non-compile time constant 

main.cpp:10:20: error: non-type template argument is not a constant expression 
const int c = tmax<list[0],list[1]>::value; // error is here 
        ^~~~~~~ 
main.cpp:10:20: note: read of non-constexpr variable 'list' is not allowed in a constant expression 
main.cpp:1:11: note: declared here 
const int list[3] = { 2, 5, 7 }; 
     ^

यह constexpr का कारण है

+0

मुझे लगता है कि कॉन्स्टेक्सर सहायक होगा, और अब जब मैं देखता हूं कि मुझे लगता है कि यह मेरे विचार से बड़ा गोद लेने वाला है। इसके साथ ही, एक स्पष्टीकरण के बारे में एक और अधिक स्पष्टीकरण के रूप में क्यों एक कॉन्स int की घोषणा करता है लेकिन सूची [1] विशेष रूप से सराहना नहीं की जाएगी। धन्यवाद। –

+0

ठीक है, तो दृश्य स्टूडियो 2012 constexpr का समर्थन करने की योजना नहीं है। किसी को भी कोई अन्य समाधान मिला है? मुझे इसके लिए इसका उपयोग नहीं करना है, लेकिन यह अच्छा होगा। –

+0

@ std''OrgnlDave मैंने संकलक डायग्नोस्टिक्स के अधिक जोड़े जो बताते हैं कि सूची [1] निरंतर अभिव्यक्ति क्यों नहीं है। – bames53

4

अभिव्यक्ति निरंतर अभिव्यक्ति नहीं हैं यदि उनमें से किसी भी अनुमत उप-अभिव्यक्तियों में से कोई एक है। अनुमति नहीं उप भाव से एक ऐसे वर्ग है:

  • एक lvalue करने वाली rvalue रूपांतरण (4.1), जब तक यह
    • है कि एक गैर को संदर्भित करता है अभिन्न या गणन प्रकार का एक glvalue लिए आवेदन किया है एक पूर्ववर्ती आरंभीकरण, एक निरंतर अभिव्यक्ति के साथ प्रारंभ साथ स्थिरांक वस्तु वाष्पशील, या
    • शाब्दिक प्रकार का एक glvalue कि एक गैर अस्थिर वस्तु constexpr के साथ परिभाषित करने के लिए संदर्भित करता है, या कि इस तरह के एक वस्तु की एक उप-वस्तु को संदर्भित करता है , या
    • शाब्दिक प्रकार का एक glvalue जो एक गैर-अस्थिर अस्थायी वस्तु को संदर्भित करता है जिसका जीवनकाल समाप्त नहीं हुआ है, निरंतर अभिव्यक्ति के साथ प्रारंभ किया गया है;

विशेष रूप से, जबकि enum या अभिन्न प्रकार एक निरंतर प्रारंभकर्ता साथ प्रारंभ की एक स्थिरांक ऑब्जेक्ट का नाम एक निरंतर अभिव्यक्ति अपने मूल्य (पढ़ने रूपों क्या lvalue करने वाली rvalue का कारण बनता है रूपांतरण), एक कॉन्स कुल ऑब्जेक्ट की उप-ऑब्जेक्ट्स (जैसे list आपके उदाहरण में, एक सरणी) नहीं, लेकिन अगर constexpr घोषित किया जाएगा।

const int list[3] = { 2, 5, 7 }; 
const int a = list[2]; 

यह मान्य है, लेकिन a एक निरंतर अभिव्यक्ति का गठन नहीं है, क्योंकि यह एक निरंतर अभिव्यक्ति साथ आरंभ नहीं किया है।

list की घोषणा को बदलकर (हमें a की घोषणा को बदलने की ज़रूरत नहीं है), हम a निरंतर अभिव्यक्ति बना सकते हैं।

constexpr int list[3] = { 2, 5, 7 }; 
const int a = list[2]; 

list[2] के रूप में अब एक निरंतर अभिव्यक्ति, a अब अभिन्न प्रकार एक निरंतर अभिव्यक्ति तो a अब एक निरंतर अभिव्यक्ति के रूप में इस्तेमाल किया जा सकता के साथ प्रारंभ की एक const वस्तु है।

+0

यह लगभग मुझे रोता है कि दृश्य स्टूडियो 2k12 constexpr का समर्थन नहीं करेगा। मैंने टेम्पलेट मेटाप्रोग्रामिंग में इस तरह के एरे का कभी भी उपयोग नहीं किया है, लेकिन मैं इसकी प्रतीक्षा कर रहा था ... –

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