संक्षिप्त उत्तर यह है कि न केवल static
उपयोगी है, यह हमेशा वांछित होने वाला है।
सबसे पहले, ध्यान दें कि static
और constexpr
एक दूसरे से पूरी तरह से स्वतंत्र हैं। static
निष्पादन के दौरान वस्तु के जीवनकाल को परिभाषित करता है; constexpr
निर्दिष्ट करता है कि ऑब्जेक्ट संकलन के दौरान उपलब्ध होना चाहिए। संकलन और निष्पादन समय और स्थान दोनों में विघटन और असंतुलित हैं। तो एक बार प्रोग्राम संकलित हो जाने पर, constexpr
अब प्रासंगिक नहीं है।
हर चर घोषित constexpr
परोक्ष const
लेकिन const
और static
लगभग ओर्थोगोनल (static const
पूर्णांकों के साथ बातचीत के लिए छोड़कर।)
C++
ऑब्जेक्ट मॉडल (§ 1.9) की आवश्यकता है कि थोड़ा-क्षेत्रों के अलावा अन्य सभी वस्तुओं पर कब्जा स्मृति की कम से कम एक बाइट और पते हैं; इसके अलावा किसी दिए गए पल में किसी कार्यक्रम में देखने योग्य ऐसी सभी वस्तुओं के अलग-अलग पते (अनुच्छेद 6) होना चाहिए। इसने संकलक को स्थानीय गैर स्थैतिक कॉन्स सरणी के साथ किसी फ़ंक्शन के प्रत्येक आमंत्रण के लिए स्टैक पर एक नई सरणी बनाने की आवश्यकता नहीं है, क्योंकि संकलक as-if
सिद्धांत में शरण ले सकता है बशर्ते यह साबित हो सके कि ऐसा कोई अन्य वस्तु नहीं कर सकता परीक्षण में रहना।
यही साबित करने के लिए आसान नहीं हो रहा है, दुर्भाग्य से, जब तक कि समारोह तुच्छ है (उदाहरण के लिए, यह किसी भी अन्य समारोह जिसका शरीर अनुवाद इकाई के भीतर दिखाई नहीं देता है फोन नहीं करता है) क्योंकि सरणियों, कम या ज्यादा परिभाषा के द्वारा, पते हैं तो ज्यादातर मामलों में, गैर-स्थैतिक const(expr)
सरणी को प्रत्येक आमंत्रण पर ढेर पर पुनर्निर्मित करना होगा, जो संकलन समय पर गणना करने में सक्षम होने के बिंदु को हरा देता है।
दूसरी तरफ, स्थानीय static const
ऑब्जेक्ट सभी पर्यवेक्षकों द्वारा साझा किया जाता है, और इसके अलावा इसे प्रारंभ किया जा सकता है भले ही इसे परिभाषित किया गया कार्य कभी भी नहीं कहा जाता है। इसलिए उपरोक्त में से कोई भी लागू नहीं होता है, और एक कंपाइलर न केवल इसके केवल एक उदाहरण उत्पन्न करने के लिए स्वतंत्र है; यह केवल पढ़ने के लिए भंडारण में इसका एक उदाहरण उत्पन्न करने के लिए स्वतंत्र है।
तो आपको निश्चित रूप से static constexpr
का उपयोग अपने उदाहरण में करना चाहिए।
हालांकि, एक ऐसा मामला है जहां आप static constexper
का उपयोग नहीं करना चाहते हैं। जब तक constexpr
घोषित ऑब्जेक्ट या तो ODR-used या घोषित static
है, तो संकलक इसे शामिल करने के लिए स्वतंत्र नहीं है। यह बहुत उपयोगी है, क्योंकि यह अनावश्यक बाइट्स के साथ संकलित प्रोग्राम को प्रदूषित किए बिना संकलन-समय अस्थायी constexpr
सरणी के उपयोग की अनुमति देता है। उस स्थिति में, आप static
का उपयोग नहीं करना चाहते हैं, क्योंकि static
ऑब्जेक्ट को रनटाइम पर मौजूद होने की संभावना है।
'constexpr' किसी भी समय संकलन समय की गारंटी नहीं देता है, संकलक रनटाइम पर 'constexpr' सामान का मूल्यांकन करने के लिए स्वतंत्र है। इसे संकलित समय पर कुछ मूल्यांकन करने के लिए मजबूर किया जाता है यदि आप उस संदर्भ में कुछ ऐसा करते हैं जहां संकलन समय पर जाना आवश्यक है। – Praetorian
मेरा मानना है कि @Praetorian सही है, और 'स्थैतिक' गारंटी नहीं देगा कि यह संकलन समय पर है, लेकिन यह केवल संकलन समय स्थिरांक के साथ संग्रहीत है। मुझे लगता है कि 'स्थिर' के बिना यह _theoretically_ समारोह के प्रत्येक आमंत्रण पर ढेर पर (विशाल) सरणी को धक्का देने के अनुरूप होगा। –
@AndrewLazarus, न केवल सैद्धांतिक रूप से प्रत्येक आमंत्रण पर सरणी को ढेर पर धक्का देने के लिए अनुरूप है, यह सैद्धांतिक रूप से आवश्यक है (जैसा कि नियम के रूप में मॉड्यूल है)। अभ्यास में, मेरे अनुभव में, यह हमेशा अच्छा होता है। अधिक जानकारी के लिए मेरा जवाब देखें। – rici