2015-11-05 5 views
6

मैं व्युत्पन्न प्रकार के static constexpr को रखने के लिए एक सीआरटीपी लिखने की कोशिश कर रहा हूं, क्योंकि यह केवल एक वर्ग के साथ असंभव है। यह कोड जीसीसी में ठीक संकलित करता है, लेकिन क्लैंग शिकायत करता है कि Derived एक अधूरा प्रकार है। कौनसा सही हैं?क्या एक क्लास परिभाषा पूर्ण है जब इसे बेस क्लास में पास किया जाता है?

template<class T> 
class Base { 
public: 
    static constexpr T a = T(1), b = T(20); 
}; 

class Derived : public Base<Derived> { 
public: 
    int x; 
    constexpr Derived(int x) : x(x) {} 
}; 
+1

व्युत्पन्न के कन्स्ट्रक्टर पर स्थानीय चर एक्स और सावधान रहें, सदस्य का नाम – Brahim

+0

है, मैं बस यह इंगित करना चाहता हूं कि बेस क्लास के अंदर स्थैतिक वस्तुओं को स्थिर रखना सबसे अच्छा विचार नहीं है .. –

+0

ऐसा करने का एकमात्र कारण इस तरह से है क्योंकि मैं 'व्युत्पन्न' प्रकार के 'स्थिर कंटेनर' को 'व्युत्पन्न' में नहीं डाल सकता। मैं ऐसा करने में सक्षम होना चाहता था: 'व्युत्पन्न :: ए' जैसे' व्युत्पन्न :: स्थिर 'जैसे कुछ। – user975989

उत्तर

2

Derived बिंदु है जिस पर Base<Derived> instantiated है ([class.mem]/2), जो सही परिभाषा समय में होता है पर अधूरा है। आपने constexpr का उपयोग किया, जो [class.static.data]/3 के अनुसार प्रारंभकर्ता को जरूरी बनाता है, और जब Base<Derived> तत्काल होता है, तो इसके स्थिर डेटा सदस्यों ([temp.inst]/3) की घोषणाएं होती हैं, जिनमें प्रारंभकर्ता शामिल होते हैं। हालांकि, प्रारंभकर्ता अपूर्ण प्रकार की वस्तु बनाने का प्रयास कर रहे हैं, जो बीमार है।

आप के रूप const बजाय अपने सदस्य की घोषणा कर सकते हैं:

template<class T> 
class Base { 
public: 
    static const T a; 
}; 
template <typename T> 
constexpr T Base<T>::a = T(1); 

के बाद से प्रारंभकर्ता परिभाषा में है, इस प्रारंभकर्ता की इन्स्टेन्शियशन जैसे जब तक आस्थगित किया जा सकता है Derived पूरा हो गया है। Clang के साथ Demo

ध्यान दें कि क्लैंग अभी तक a को constexpr के रूप में नहीं मानता है क्योंकि यह उत्सुकता से इसकी परिभाषा को तुरंत विफल करने में विफल रहता है। बग #24541 देखें।

+0

देखता हूं लेकिन फिर आप 'static_assert (व्युत्पन्न :: कुल्हाड़ी == 1," ") 'नहीं कर सकते हैं, जो कि' constexpr' के उद्देश्य को हरा देता है। – user975989

+0

@ user975989 यह एक क्लैंग बग प्रतीत होता है। – Columbo

+0

@ user975989 डीआर मिला और इसे उत्तर में जोड़ा गया। (काफी हद तक, उदाहरण का इस्तेमाल बिंदु पर बहुत अधिक है!) – Columbo

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