दिलचस्प पोस्ट
दो divs, एक निश्चित चौड़ाई, दूसरे, बाकी एसक्यूएल प्रदर्शन यूनियन बनाम या अक्षमता की अवधि के बाद उपयोगकर्ताओं को अपने आप लॉग ऑन कैसे करें? HttpServletRequest यूटीएफ -8 एन्कोडिंग जावा में डायनामिक जेनेरिक टाइपिंग NSData को उद्देश्य सी में NSString में बदलने WPF में सत्यापन त्रुटि शैली, सिल्वरलाइट के समान सभी jQuery अजाक्स अनुरोध किया जाता है जब तक प्रतीक्षा करें? इनलाइन / इनलाइन-ब्लॉक तत्वों के CSS ऊर्ध्वाधर संरेखण एंड्रॉइड 6.0 ओपन विफल: EACCES (अनुमति अस्वीकृत) जेपीएनएल जो दर्शकों में से एक है दृश्यता के लिए उचित है सी # में किसी पाठ फ़ाइल की एक विशिष्ट पंक्ति को संपादित करें समान मूल्यों के निकटवर्ती चालकों को सूचकांक जोड़ें पता लगाएँ कि प्रोग्राम पूर्ण व्यवस्थापक अधिकारों के साथ चल रहा है यह निर्धारित करने के लिए कि कौन से ऐप्स पृष्ठभूमि हैं और कौन से ऐप आइपॉड पर अनुप्रयोग आईडी द्वारा अग्रभूमि पर है

`Constexpr` और` const` के बीच का अंतर

constexpr और const बीच अंतर क्या है?

  • जब मैं उनमें से केवल एक का उपयोग कर सकता हूँ?
  • मैं दोनों का उपयोग कैसे कर सकता हूं और मुझे एक कैसे चुनना चाहिए?

वेब के समाधान से एकत्रित समाधान "`Constexpr` और` const` के बीच का अंतर"

मूल अर्थ और वाक्यविन्यास

दोनों खोजशब्दों का प्रयोग वस्तुओं के घोषित होने के साथ-साथ कार्यों में किया जा सकता है। ऑब्जेक्ट पर लागू होने पर बुनियादी अंतर यह है:

  • const एक ऑब्जेक्ट को निरंतर बताता है इससे एक गारंटी है कि, एक बार आरम्भ करने के बाद, उस ऑब्जेक्ट का मूल्य नहीं बदलेगा, और अनुकूलक के लिए संकलक इस तथ्य का उपयोग कर सकता है। यह प्रोग्रामर को लिखे गए कोड को लिखने से रोकने में मदद करता है जो ऑब्जेक्ट्स को संशोधित करता है जो आरंभीकरण के बाद संशोधित नहीं किया गया था।

  • constexpr एक ऑब्जेक्ट के रूप में मानक को निरंतर अभिव्यक्ति कॉल में उपयोग के लिए फिट के रूप में घोषित करता है। लेकिन ध्यान दें कि ऐसा करने का एकमात्र तरीका नहीं है।

फ़ंक्शन पर लागू होने पर बुनियादी अंतर यह है:

  • const केवल गैर-स्थिर सदस्य कार्यों के लिए इस्तेमाल किया जा सकता है, सामान्य रूप में कार्य नहीं करता है यह गारंटी देता है कि सदस्य फ़ंक्शन किसी भी गैर-स्थिर डेटा सदस्यों को संशोधित नहीं करता है।

  • constexpr का उपयोग सदस्य और गैर-सदस्यीय कार्यों के साथ-साथ constexpr साथ भी किया जा सकता है। यह निरंतर अभिव्यक्तियों में उपयोग के लिए फ़ंक्शन फिट की घोषणा करता है कम्पाइलर केवल इसे स्वीकार करेगा यदि फ़ंक्शन कुछ महत्वपूर्ण मानदंड (7.1.5 / 3,4) को पूरा करता है, सबसे महत्वपूर्ण (†) :

    • फ़ंक्शन बॉडी को गैर-वर्चुअल और बेहद सरल होना चाहिए: टाइपिंगफेस और स्टैटिक असाधारण के अलावा, केवल एकल return स्टेटमेंट की अनुमति है। एक कन्स्ट्रक्टर के मामले में, केवल एक प्रारंभिक सूची, टाइपिंग और स्थैतिक जोर की अनुमति है। ( = default और = delete की अनुमति है, हालांकि, हालांकि।)
    • तर्क और रिटर्न प्रकार शाब्दिक प्रकार होना चाहिए (यानी, आम तौर पर बोलना, बहुत सरल प्रकार, आमतौर पर स्केलेर्स या समुच्चय)

लगातार भाव

जैसा कि ऊपर कहा गया है, constexpr दोनों वस्तुओं के साथ ही निरंतर अभिव्यक्ति में उपयोग के लिए कार्य के रूप में घोषित करता है। निरंतर अभिव्यक्ति केवल स्थिर से अधिक है:

  • इसका उपयोग उन स्थानों में किया जा सकता है, जिन्हें संकलन-समय मूल्यांकन की आवश्यकता होती है, उदाहरण के लिए, टेम्पलेट पैरामीटर और ऑर्गे-आकार विनिर्देशक:

     template<int N> class fixed_size_list { /*...*/ }; fixed_size_list<X> mylist; // X must be an integer constant expression int numbers[X]; // X must be an integer constant expression 
  • लेकिन ध्यान दें:

    • constexpr रूप में कुछ घोषित करना जरूरी नहीं है कि यह संकलन समय पर मूल्यांकन किया जाएगा। इसका उपयोग इस तरह के लिए किया जा सकता है , लेकिन इसे अन्य स्थानों में उपयोग किया जा सकता है जो कि रन-टाइम में मूल्यांकन किया जाता है, साथ ही साथ।

    • एक वस्तु स्थिर अभिव्यक्ति के बिना निरंतर अभिव्यक्ति में उपयोग के लिए फिट हो सकती है उदाहरण:

       int main() { const int N = 3; int numbers[N] = {1, 2, 3}; // N is constant expression return 0; } 

    यह संभव है क्योंकि N निरंतर और एक शाब्दिक शब्द के साथ घोषणा समय पर आरंभ किया जाता है, निरंतर अभिव्यक्ति के लिए मानदंडों को संतुष्ट करता है, भले ही इसे constexpr घोषित नहीं किया constexpr

तो जब मैं वास्तव में constexpr का उपयोग constexpr ?

  • उपर्युक्त N तरह एक ऑब्जेक्ट को स्थिर अभिव्यक्ति के रूप में स्थिर अभिव्यक्ति के बिना इस्तेमाल किया जा सकता है ये सभी वस्तुओं के लिए सच है:

    • const
    • अभिन्न या गणना प्रकार का और
    • एक अभिव्यक्ति के साथ घोषणा समय पर आरंभ किया गया है जो कि एक निरंतर अभिव्यक्ति है

    [यह §5.19 / 2 की वजह से है: एक निरंतर अभिव्यक्ति में एक उप-अभिव्यक्ति शामिल नहीं होना चाहिए जिसमें "[…] अभिन्न या गणना प्रकार का एक ग्लव्यू […] जब तक रिचर्ड स्मिथ के लिए धन्यवाद" पहले दावा करते हैं कि यह सभी शाब्दिक प्रकारों के लिए सच था।]

  • निरंतर अभिव्यक्ति में उपयोग के लिए उपयुक्त होने के लिए फ़ंक्शन को स्पष्ट रूप से घोषित किया जाना चाहिए; यह निरंतर अभिव्यक्ति कार्यों के लिए मानदंडों को पूरा करने के लिए पर्याप्त नहीं है। उदाहरण:

     template<int N> class list { }; constexpr int sqr1(int arg) { return arg * arg; } int sqr2(int arg) { return arg * arg; } int main() { const int X = 2; list<sqr1(X)> mylist1; // OK: sqr1 is constexpr list<sqr2(X)> mylist2; // wrong: sqr2 is not constexpr return 0; } 

मैं कब, const और constexpr दोनों का उपयोग कर सकता / सकती हूं ?

ऑब्जेक्ट घोषणाओं में ए। यह कभी आवश्यक नहीं होता है जब दोनों खोजशब्द एक ही ऑब्जेक्ट को घोषित करने के लिए कहते हैं constexpr मतलब है const

 constexpr const int N = 5; 

के समान है

 constexpr int N = 5; 

हालांकि, ध्यान दें कि जब भी कीवर्ड प्रत्येक घोषणा के विभिन्न हिस्सों का उल्लेख करते हैं, तब हालात भी हो सकते हैं:

 static constexpr int N = 3; int main() { constexpr const int *NP = &N; return 0; } 

यहां, NP को निरंतर अभिव्यक्ति के रूप में घोषित किया जाता है, यानी एक सूचक जो कि एक निरंतर अभिव्यक्ति है (यह संभव है जब पता ऑपरेटर को स्थैतिक / वैश्विक स्थिर अभिव्यक्ति के लिए आवेदन करके उत्पन्न किया जाता है।) यहाँ, दोनों constexpr और const आवश्यक हैं: constexpr हमेशा अभिव्यक्ति (यहाँ NP ) घोषित करने के लिए संदर्भित करता है, जबकि const int संदर्भित करता है (यह एक सूचक-टू-कंट घोषित करता है) const को हटाने से अभिव्यक्ति को अवैध रूप से प्रस्तुत किया जाएगा (क्योंकि (ए) एक गैर-कॉन्स्ट ऑब्जेक्ट के लिए एक पॉइंट एक निरंतर अभिव्यक्ति नहीं हो सकता, और (बी) &N वास्तव में एक पॉइंटर-टू-स्ट्रेस) है।

सदस्य कार्य घोषणा में बी। सी ++ 11 में, constexpr सदस्य कार्यों के लिए भी const हालांकि, यह सी ++ 14 में बदलने की संभावना है वर्तमान ड्राफ्ट के अनुसार, constexpr केवल वस्तुओं के लिए constexpr होगा, न कि सदस्य कार्यों के लिए, §7.1.5 / 8 के लिए प्रस्तावित परिवर्तन के कारण इसलिए, एक सदस्य कार्य सी ++ 11 के तहत घोषित किया गया है

 constexpr void f(); 

के रूप में घोषित किया जाना होगा

 constexpr void f() const; 

सी ++ 14 के तहत अब भी const फ़ंक्शन के रूप में प्रयोग करने योग्य हो सकता है। अपने constexpr सदस्य कार्यों को अब भी constexpr रूप में चिह्नित करें ताकि बाद में बहुत सारे कोड बदल सकें।


(†) स्वीकार्य constexpr कार्यों के लिए शर्तों को शायद सी + + 14 के लिए आराम किया जाएगा रिचर्ड स्मिथ द्वारा एक प्रस्ताव को हाल ही में सी ++ 14 प्रारूप में अपनाया गया है ।

const वेरिएबल के लिए लागू होता है, और उन्हें आपके कोड में संशोधित होने से रोकता है

constexpr कंपाइलर को बताता है कि यह अभिव्यक्ति एक संकलन समय निरंतर मान में परिणाम है, तो यह सरणी लंबाई जैसी जगहों में इस्तेमाल किया जा सकता है, constexpr लिए निर्दिष्ट किया जा सकता है। ओली द्वारा दिए गए लिंक में उत्कृष्ट उदाहरण हैं।

असल में वे पूरी तरह से 2 अलग-अलग अवधारणाएं हैं, और एक साथ (और इन्हें) इस्तेमाल किया जा सकता है

अवलोकन

  • const गारंटी देता है कि कोई प्रोग्राम ऑब्जेक्ट के मान को परिवर्तित नहीं करता है हालाँकि, const यह गारंटी नहीं देता है कि ऑब्जेक्ट किस प्रकार का प्रारंभ होता है।

    विचार करें:

     const int mx = numeric_limits<int>::max(); // OK: runtime initialization 

    समारोह max() केवल एक शाब्दिक मूल्य देता है हालांकि, क्योंकि प्रारंभकर्ता एक फ़ंक्शन कॉल है, mx रनटाइम आरंभीकरण से गुजरता है। इसलिए, आप इसे निरंतर अभिव्यक्ति के रूप में नहीं उपयोग कर सकते हैं:

     int arr[mx]; // error: “constant expression required” 
  • constexpr एक नया C + + 11 कीवर्ड है जो मैक्रोज़ और हार्डकोडेड लिटरल्स बनाने की आवश्यकता के बारे में constexpr है। यह कुछ शर्तों के तहत भी गारंटी देता है, कि ऑब्जेक्ट्स स्थैतिक आरंभीकरण से गुज़रते हैं। यह अभिव्यक्ति के मूल्यांकन समय को नियंत्रित करता है। अपनी अभिव्यक्ति के संकलन-समय के मूल्यांकन को लागू करके, constexpr आपको सही निरंतर अभिव्यक्तियों को परिभाषित करने देता है जो समय-महत्वपूर्ण अनुप्रयोगों, सिस्टम प्रोग्रामिंग, टेम्पलेट्स और आम तौर पर बोलते हुए, किसी भी कोड में, जो संकलन-समय स्थिरांक पर निर्भर करता है, के लिए महत्वपूर्ण हैं।

निरंतर अभिव्यक्ति कार्य

एक निरंतर अभिव्यक्ति फ़ंक्शन एक समारोह घोषित constexpr इसका शरीर गैर-आभासी होना चाहिए और इसमें केवल सिंगल रिटर्न स्टेटमेंट होना चाहिए, इसके अलावा टाइपफीफेस और स्टैटिक इनरटेंस के अलावा इसका तर्क और रिटर्न वैल्यू में शाब्दिक प्रकार होने चाहिए। इसका उपयोग गैर-निरंतर अभिव्यक्ति तर्क के साथ किया जा सकता है, लेकिन जब ऐसा किया जाता है तो परिणाम निरंतर अभिव्यक्ति नहीं है।

एक निरंतर अभिव्यक्ति फ़ंक्शन का अर्थ है प्रदर्शन या प्रकार की सुरक्षा का त्याग किए बिना मैक्रोज़ और हार्डकोडेड लिटरल्स को प्रतिस्थापित करना।

 constexpr int max() { return INT_MAX; } // OK constexpr long long_max() { return 2147483647; } // OK constexpr bool get_val() { bool res = false; return res; } // error: body is not just a return statement constexpr int square(int x) { return x * x; } // OK: compile-time evaluation only if x is a constant expression const int res = square(5); // OK: compile-time evaluation of square(5) int y = getval(); int n = square(y); // OK: runtime evaluation of square(y) 

लगातार अभिव्यक्ति वस्तुओं

निरंतर अभिव्यक्ति ऑब्जेक्ट एक ऑब्जेक्ट घोषित constexpr । इसे निरंतर अभिव्यक्ति या एक निरंतर अभिव्यक्ति कंस्ट्रक्टर द्वारा निरंतर अभिव्यक्ति तर्कों के द्वारा बनाए गए एक rvalue के साथ आरंभ किया जाना चाहिए।

एक निरंतर अभिव्यक्ति वस्तु व्यवहार करती है जैसे कि इसे const घोषित किया गया था, सिवाय उसके उपयोग के पहले आरंभीकरण की आवश्यकता होती है और इसकी प्रारंभिकता निरंतर अभिव्यक्ति होनी चाहिए। नतीजतन, एक निरंतर अभिव्यक्ति वस्तु हमेशा एक निरंतर अभिव्यक्ति के भाग के रूप में उपयोग की जा सकती है।

 struct S { constexpr int two(); // constant-expression function private: static constexpr int sz; // constant-expression object }; constexpr int S::sz = 256; enum DataPacket { Small = S::two(), // error: S::two() called before it was defined Big = 1024 }; constexpr int S::two() { return sz*2; } constexpr S s; int arr[s.two()]; // OK: s.two() called after its definition 

निरंतर अभिव्यक्ति कंस्ट्रक्टर

एक निरंतर अभिव्यक्ति कंस्ट्रक्टर एक निर्माता घोषित constexpr । इसमें सदस्य आरंभीकरण सूची हो सकती है लेकिन इसका शरीर खाली होना चाहिए, इसके अलावा टाइपफीफेस और स्थैतिक आधार के अलावा इसके तर्कों में शाब्दिक प्रकार होने चाहिए।

एक निरंतर अभिव्यक्ति कंस्ट्रक्टर कंपाइलर को संकलन-समय पर ऑब्जेक्ट को इनिइज़ करने की अनुमति देता है, बशर्ते कन्स्ट्रक्टर के तर्क सभी निरंतर अभिव्यक्तियाँ हैं।

 struct complex { // constant-expression constructor constexpr complex(double r, double i) : re(r), im(i) { } // OK: empty body // constant-expression functions constexpr double real() { return re; } constexpr double imag() { return im; } private: double re; double im; }; constexpr complex COMP(0.0, 1.0); // creates a literal complex double x = 1.0; constexpr complex cx1(x, 0); // error: x is not a constant expression const complex cx2(x, 1); // OK: runtime initialization constexpr double xx = COMP.real(); // OK: compile-time initialization constexpr double imaglval = COMP.imag(); // OK: compile-time initialization complex cx3(2, 4.6); // OK: runtime initialization 

पुस्तक से युक्तियाँ प्रभावी आधुनिक सी ++ स्कॉट मेयेर्स के बारे में constexpr बारे में:

  • constexpr वस्तुओं const हैं और संकलन के दौरान ज्ञात मूल्यों के साथ प्रारंभ किया जाता है;
  • constexpr फ़ंक्शंस constexpr -टाइम परिणाम का उत्पादन करता है, जब उस तर्क के साथ बुलाया जाता है जिसका मूल्य संकलन के दौरान जाना जाता है;
  • constexpr ऑब्जेक्ट्स और फ़ंक्शंस का प्रयोग गैर- constexpr ऑब्जेक्ट्स और फ़ंक्शंस की तुलना में व्यापक संदर्भों में किया जा सकता है;
  • constexpr एक ऑब्जेक्ट या फ़ंक्शन के इंटरफ़ेस का हिस्सा है।

स्रोत: सी ++ में सुरक्षा, प्रदर्शन और एन्कैप्शन में सुधार करने के लिए constexpr का उपयोग करना

बर्न स्ट्राफ्रुप द्वारा "सी ++ प्रोग्रामिंग भाषा 4 वीं एडिटॉन" की पुस्तक के अनुसार
कस्ट : अर्थ लगभग '' मैं यह मान नहीं बदला '' (§7.5)। यह मुख्य रूप से इंटरफेस को निर्दिष्ट करने के लिए प्रयोग किया जाता है, ताकि डेटा को फ़ंक्शन को पारित किया जा सकता है इसके बिना इसे संशोधित किया जा रहा है
कंपाइलर const द्वारा किए गए वादे को लागू करता है
स्थिरता : जिसका अर्थ लगभग 'संकलन समय पर मूल्यांकन किया जाना' (§10.4)। यह मुख्य रूप से स्थिरांक निर्दिष्ट करने के लिए प्रयोग किया जाता है, ताकि अनुमति हो सके
उदाहरण के लिए:

 const int dmv = 17; // dmv is a named constant int var = 17; // var is not a constant constexpr double max1 = 1.4*square(dmv); // OK if square(17) is a constant expression constexpr double max2 = 1.4∗square(var); // error : var is not a constant expression const double max3 = 1.4∗square(var); //OK, may be evaluated at run time double sum(const vector<double>&); // sum will not modify its argument (§2.2.5) vector<double> v {1.2, 3.4, 4.5}; // v is not a constant const double s1 = sum(v); // OK: evaluated at run time constexpr double s2 = sum(v); // error : sum(v) not constant expression 

फ़ंक्शन को एक स्थिर अभिव्यक्ति में प्रयोग करने योग्य होने के लिए, यह एक अभिव्यक्ति में है जिसे संकलक द्वारा मूल्यांकन किया जाएगा, इसे परिभाषित किया जाना चाहिए constexpr
उदाहरण के लिए:

 constexpr double square(double x) { return x∗x; } 

Constexpr होना करने के लिए, एक समारोह बल्कि सरल होना चाहिए: सिर्फ एक वापसी-बयान एक मूल्य की गणना। एक constexpr फ़ंक्शन का उपयोग गैर-निरंतर तर्कों के लिए किया जा सकता है, लेकिन जब ऐसा किया जाता है, परिणाम निरंतर अभिव्यक्ति नहीं होता है हम एक constexpr फ़ंक्शन को संदर्भ में गैर-निरंतर अभिव्यक्ति तर्कों के साथ बुलाया जाने की अनुमति देते हैं, जिन्हें निरंतर अभिव्यक्ति की आवश्यकता नहीं होती है, ताकि हम अनिवार्य रूप से एक ही समारोह को दो बार परिभाषित न करें: एक बार स्थिर अभिव्यक्ति के लिए और एक बार चर के लिए।
कुछ जगहों पर, भाषा के नियमों (उदा। सरणी सीमा (§2.2.5, §7.3), केस लेबल्स (§2.2.4, § 9.4.2), कुछ टेम्पलेट तर्क (§25.2), और स्थिरांक का उपयोग करके घोषित स्थिरांक) अन्य मामलों में, प्रदर्शन के लिए संकलित समय मूल्यांकन महत्वपूर्ण होता है। स्वतंत्रता के मुद्दों के स्वतंत्र रूप से, अपरिवर्तनीयता की धारणा (एक अपरिवर्तनीय राज्य के साथ किसी वस्तु का) एक महत्वपूर्ण डिजाइन चिंता (§10.4) है।

@ 0x499602d2 के रूप में पहले से ही बताया गया है, const केवल यह सुनिश्चित करता है कि प्रारंभिकरण के बाद एक मान को बदला नहीं जा सकता है, जैसे कि constexpr (सी constexpr पेश किया गया) चर की गारंटी देता है कि एक संकलन समय स्थिर है
निम्न उदाहरण पर विचार करें (LearnCpp.com से):

 cout << "Enter your age: "; int age; cin >> age; const int myAge{age}; // works constexpr int someAge{age}; // error: age can only be resolved at runtime