2016-09-22 12 views
9

जहां तक ​​मैं देख सकता हूँ, एक बहुत ही सामान्य स्थिति की तरह कुछ हैconstexpr स्थिर सदस्य से पहले/के बाद सी ++ 17

template<int i> class Class 
{ 
public: 
    static constexpr int I = i; 
    static constexpr int J = constexprFunction(i); 
    // further Class implementation 
}; 

लगभग के रूप में आम मैं गलती (देखें यहां तथ्य मेरे सवालों के अधिकांश में हैं क्योंकि मैं इसे भूल गया और पता नहीं था, क्या उचित सवाल किया गया था) अतिरिक्त परिभाषा यदि सदस्य ओडीआर-उपयोग किया जाता है भूल जाते हैं:

template<int i> constexpr int Class<i>::I; 
template<int i> constexpr int Class<i>::J; 

अब मैं cppreference: Definitions and ODR और cppreference: static members है, जो राज्य पढ़ा है, कि इस बहिष्कृत हो गई है सी ++ 17 के लिए। यह मेरे लिए बहुत अच्छा लगता है, क्योंकि यह बहुत सारी त्रुटियों से बचाता है। लेकिन अन्य प्रश्न हैं, जो आए:

1) क्या अतिरिक्त परिभाषा बेकार बनाने के अलावा अन्य कारणों में यह बदलाव आया है? (इस प्रश्न का अंतिम पैराग्राफ भी देखें)

2) cppreference: static members के अंतिम उदाहरण में यह const static सदस्य पर भी लागू होता है - लेकिन नियम केवल constexpr सदस्य बताता है। क्या यह const static सदस्य पर लागू होगा या नहीं?

3) सभी उदाहरण मैं Class::I की तरह एक साधारण परिभाषा उपयोग कर रहे थे पाया - यह सब constexpr कार्यों के साथ Class:J पर स्थिति के लिए भी पकड़ करता है?

एक संक्षिप्त स्थिति सी ++ 17 से पहले सर्वोत्तम अभ्यास क्या है और सी ++ 17 के साथ बहुत अच्छा होगा। यह सब मेरे लिए एक बहुत ही मुश्किल बदलाव लगता है, क्योंकि यह बहुत अच्छा कोड बना देगा, जो पहले से खराब कोड (जहां तक ​​मैं समझता हूं ...) के लिए "खराब गठित गैर नैदानिक ​​आवश्यक" था। और इसके परिणामस्वरूप कोड बनाया जाएगा, जो अभी भी पुराने (पूर्व 17) कंपाइलर के साथ "खराब गठित गैर डायग्नोस्टिक आवश्यक" है - लेकिन जब तक कोई ओडीआर-उपयोग की आवश्यकता नहीं है, तब तक ये शिकायत नहीं करेंगे।

संपादित करें: हारून मैकडैड द्वारा सुझाए गए पाठ को सही किया गया।

+2

मुझे लगता है कि स्थैतिक डेटा सदस्यों पर अंतिम उदाहरण एक संपादन त्रुटि थी (अब तय): 9.2.3.2 [class.static.data] p3 कहता है, "गैर-अस्थिर गैर-इनलाइन स्थिर स्थिर डेटा सदस्य" के लिए, " यदि सदस्य ओडीआर-प्रयुक्त होता है तो सदस्य को अभी भी नामस्थान स्कोप में परिभाषित किया जाएगा " – Cubbi

+1

मैं वर्तमान में इस प्रश्न में पाठ से उलझन में हूं: *" गलती ... यदि सदस्यों का उपयोग किया जाता है तो परिभाषा देने के लिए "*। निश्चित रूप से आपका मतलब है, उदाहरण के लिए सी ++ 11 में, यह परिभाषा देने के लिए * असफल * की गलती है? क्या आप एक अस्वीकार भूल गए? (क्षमा करें अगर यह बहुत pedantic लगता है, लेकिन मैं वास्तव में इस इरादे के बारे में सुनिश्चित करने के लिए पर्याप्त रूप से यह नहीं जानता) –

+0

@AaronMcDaid हाँ, यह सच है। मैंने ठीक कर दिया। मुझे स्पष्ट रूप से मतलब था कि सी ++ 11 में अतिरिक्त परिभाषा देना आवश्यक है, लेकिन यह अब सी ++ 17 में सच नहीं है। इसलिए मैंने पिछले पैराग्राफ में नीचे की संगतता के उद्देश्य से अपने भ्रम की व्याख्या करने की कोशिश की। – marlam

उत्तर

5

यह परिवर्तन इनलाइन चर प्रस्ताव (P0386) के कारण है। static constexpr परिभाषाओं को अनावश्यक बनाने, inline का संकेत देगा।

अनुलग्नक डी में, एक नया उपखंड, "पुन: घोषणा स्थिर constexpr डेटा सदस्यों की" DX निम्नलिखित सामग्री के साथ जोड़ने के लिए,: पूर्व सी ++ अंतरराष्ट्रीय मानकों के साथ संगतता के , एक constexpr स्थिर डेटा सदस्य प्रचुरता से बाहर redeclared किया जा सकता है कोई प्रारंभकर्ता के साथ कक्षा। यह उपयोग बहिष्कृत है।

[उदाहरण:

struct A { 
static constexpr int n = 5; // definition (declaration in C++2014) 
}; 
const int A::n; // redundant declaration (definition in C++2014) 

अंत उदाहरण]

के बारे में अपने प्रश्नों के:

इस परिवर्तन अतिरिक्त परिभाषाओं बेकार बनाने के अलावा अन्य कारण है?

संक्षेप में, नहीं। इसके बावजूद आपके पास उल्लेख किए गए अतिरिक्त उपयोग हैं (यह question देखें)। यह प्रस्ताव विवादास्पद था क्योंकि यह एक परिवर्तनीय वैश्विक राज्य के उपयोग को प्रोत्साहित कर सकता है।

क्या यह const static सदस्य पर लागू होगा या नहीं?

सं जब तक आप inline के रूप में उस पर टिप्पणी करें।

यह सब constexpr कार्यों के साथ Class:J पर स्थिति के लिए भी पकड़ करता है?

हां। प्रस्ताव लिंकिंग के साथ सौदा करता है लेकिन प्रारंभिक नियमों को प्रभावित नहीं करता है।

+0

मुझे पता है कि यह एक उद्धरण है, लेकिन क्या यह 'constexpr' घोषित करने और इसे' कॉन्स्ट' 'के रूप में परिभाषित करने में थोड़ा उलझन में नहीं है? क्योंकि ऐसा लगता है कि मैं वही नहीं हूं ... – marlam

+0

@marlam यह मुझे भी हैरान कर दिया। मुझे लगता है कि यह एक टाइपो है। – metalfox

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