2016-04-26 15 views
6

निम्नलिखित कोड पर विचार करें जीसीसी के संस्करण 4.9 से 5.3 तक और मुझे एक ही त्रुटि मिलती है (आप इसे गॉडबॉल्ट here पर आजमा सकते हैं)। बजना भी static_assert बिना यह संकलित करने के लिए मना कर दिया है, और शिकायत है किसंकलक त्रुटि static_assert साथ CRTP का उपयोग कर

error: no member named 'x_derived' in 'Derived' 
static constexpr int x_base = Derived::x_derived; 

कौन सा संकलक सही है (यदि हो)? क्या कोड को ठीक करने का कोई अच्छा तरीका है?

उत्तर

9

नेस्टेड नाम तक पहुँचना वर्ग पूरा होने की आवश्यकता है, लेकिन Derived यहाँ अभी तक पूरा नहीं हुआ है:

template<typename Derived> 
struct Base { 
    static constexpr int x_base = Derived::x_derived; 
            ^^^^^^^^^ 
}; 

तो कोड बीमार ही बना है।

कुछ कामकाज हैं।

template <typename Derived, int x_derived> 
struct Base { 
    static constexpr int x_base = x_derived; 
}; 

struct Derived : public Base<Derived, 5> { }; 

दूसरा, यदि संभव हो तो (उदाहरण के लिए आप x_derived की जरूरत नहीं है किसी भी सदस्य घोषित करने के लिए), तो आपको देरी करने के लिए एक समारोह में मूल्य ले जा सकते हैं: सबसे पहले, आप अलग से बस मूल्य में एक टेम्पलेट तर्क के रूप में पारित कर सकते हैं इसका तात्कालिकता:

template<typename Derived> 
struct Base { 
    static constexpr int x_base() { 
     static_assert(Derived::x_derived > 1, "Oops"); 
     return Derived::x_derived; 
    } 

}; 

struct Derived : public Base<Derived> { 
    static constexpr int x_derived = 5; 
}; 
+0

महान उत्तर बैरी के लिए धन्यवाद। इसलिए, अगर मैं आपको सही ढंग से समझता हूं, तो तथ्य यह है कि gcc static_assert के बिना कोड स्वीकार करता है एक कंपाइलर बग है, और क्लैंग इसे अस्वीकार करने में सही है? – toth

+1

@toth gcc इसे तब तक अस्वीकार नहीं करता जब तक आप वास्तव में इसे कहीं भी उपयोग नहीं करते - इसलिए यह उस सम्मान में थोड़ा सा मित्रवत है। लेकिन यह वास्तव में एक वेरिएबल घोषित करने के लिए वास्तव में सार्थक नहीं है जिसका आप कभी भी उपयोग नहीं करते हैं - इसलिए यह सही तरीके से अस्वीकार करता है जहां यह महत्वपूर्ण है। – Barry

+0

लेकिन जीसीसी मुझे इसका उपयोग करने देता है, जब तक कि यह static_assert में न हो। उदा।, Https://godbolt.org/g/rfbH5c (जबकि क्लैंग कोड को अस्वीकार करना जारी रखता है)। तो संकलक में से एक गलत होना चाहिए, कोई विचार जो? – toth

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