C++11: Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
Line 15: Line 15:
* वास्तविक दुनिया की समस्याओं के लिए उचित समाधान प्रदान करें
* वास्तविक दुनिया की समस्याओं के लिए उचित समाधान प्रदान करें
* शून्य-ओवरहेड सिद्धांत लागू करें (कुछ उपयोगिताओं द्वारा आवश्यक अतिरिक्त समर्थन का उपयोग तभी किया जाना चाहिए जब उपयोगिता का उपयोग किया जाता है)
* शून्य-ओवरहेड सिद्धांत लागू करें (कुछ उपयोगिताओं द्वारा आवश्यक अतिरिक्त समर्थन का उपयोग तभी किया जाना चाहिए जब उपयोगिता का उपयोग किया जाता है)
* विशेषज्ञ प्रोग्रामरों द्वारा आवश्यक किसी भी उपयोगिता को हटाए बिना सी ++ को पढ़ाने और सीखने में आसान बनाएं
* विशेषज्ञ प्रोग्रामरों द्वारा आवश्यक किसी भी उपयोगिता को हटाए बिना सी ++ को पढ़ाने और सीखने में सरल बनाएं


शुरुआती लोगों पर ध्यान देना महत्वपूर्ण माना जाता है, क्योंकि अधिकांश कंप्यूटर प्रोग्रामर सदैव ऐसे ही होते हैं, और क्योंकि कई शुरुआती अपने ज्ञान को कभी भी विस्तृत नहीं करते हैं, खुद को उस भाषा के पहलुओं में कार्य करने के लिए सीमित करते हैं जिसमें वे विशेषज्ञ होते हैं।{{Ref|web-strou-brief}}
शुरुआती लोगों पर ध्यान देना महत्वपूर्ण माना जाता है, क्योंकि अधिकांश कंप्यूटर प्रोग्रामर सदैव ऐसे ही होते हैं, और क्योंकि कई शुरुआती अपने ज्ञान को कभी भी विस्तृत नहीं करते हैं, खुद को उस भाषा के पहलुओं में कार्य करने के लिए सीमित करते हैं जिसमें वे विशेषज्ञ होते हैं।{{Ref|web-strou-brief}}
Line 119: Line 119:


=== कोर भाषा प्रयोज्य संवर्द्धन ===
=== कोर भाषा प्रयोज्य संवर्द्धन ===
भाषा को उपयोग में आसान बनाने के प्राथमिक उद्देश्य के लिए ये सुविधाएं सम्मिलित हैं। ये प्रकार की सुरक्षा में सुधार कर सकते हैं, कोड पुनरावृत्ति को कम कर सकते हैं, गलत कोड की संभावना कम कर सकते हैं, आदि।
भाषा को उपयोग में सरल बनाने के प्राथमिक उद्देश्य के लिए ये सुविधाएं सम्मिलित हैं। ये प्रकार की सुरक्षा में सुधार कर सकते हैं, कोड पुनरावृत्ति को कम कर सकते हैं, गलत कोड की संभावना कम कर सकते हैं, आदि।


==== प्रारंभकर्ता सूचियां ====
==== प्रारंभकर्ता सूचियां ====
Line 215: Line 215:


==== टाइप अनुमान ====
==== टाइप अनुमान ====
सी ++ 03 (और सी) में, एक चर का उपयोग करने के लिए, इसके प्रकार को स्पष्ट रूप से निर्दिष्ट किया जाना चाहिए। चूंकि, टेम्प्लेट प्रकार और टेम्प्लेट मेटाप्रोग्रामिंग तकनीकों के आगमन के साथ, किसी चीज़ का प्रकार, विशेष रूप से किसी फ़ंक्शन का अच्छी तरह से परिभाषित वापसी मूल्य, आसानी से व्यक्त नहीं किया जा सकता है। इस प्रकार, इंटरमीडिएट्स को वेरिएबल्स में स्टोर करना मुश्किल है, संभवतः किसी दिए गए मेटाप्रोग्रामिंग लाइब्रेरी के इंटर्नल्स के ज्ञान की आवश्यकता है।
सी ++ 03 (और सी) में, एक चर का उपयोग करने के लिए, इसके प्रकार को स्पष्ट रूप से निर्दिष्ट किया जाना चाहिए। चूंकि, टेम्प्लेट प्रकार और टेम्प्लेट मेटाप्रोग्रामिंग तकनीकों के आगमन के साथ, किसी चीज़ का प्रकार, विशेष रूप से किसी फ़ंक्शन का अच्छी तरह से परिभाषित वापसी मूल्य, सरली से व्यक्त नहीं किया जा सकता है। इस प्रकार, इंटरमीडिएट्स को वेरिएबल्स में स्टोर करना मुश्किल है, संभवतः किसी दिए गए मेटाप्रोग्रामिंग लाइब्रेरी के इंटर्नल्स के ज्ञान की आवश्यकता है।


सी ++ 11 इसे दो तरीकों से कम करने की अनुमति देता है। सबसे पहले, एक स्पष्ट प्रारंभ के साथ एक चर की परिभाषा का उपयोग कर सकते हैं <code>auto</code> कीवर्ड।<ref>{{cite web |url=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1478.pdf |author1=Jaakko Järvi |author2=Bjarne Stroustrup |author3=Douglas Gregor |author4=Jeremy Siek |title=Decltype and auto, Programming Language C++, Document no: N1478=03-0061 |date=April 28, 2003 |access-date=June 6, 2015 |archive-date=May 28, 2015 |archive-url=https://web.archive.org/web/20150528112722/http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1478.pdf |url-status=live }}</ref><ref>{{cite web|url=http://accu.org/index.php/journals/1859|title="Auto – A Necessary Evil?" Overload Journal #115|author=Roger Orr|date=June 2013|access-date=2015-06-06|archive-date=2015-06-06|archive-url=https://web.archive.org/web/20150606155637/http://accu.org/index.php/journals/1859|url-status=live}}</ref> यह विशिष्ट प्रकार के प्रारंभकर्ता का एक चर बनाता है:
सी ++ 11 इसे दो तरीकों से कम करने की अनुमति देता है। सबसे पहले, एक स्पष्ट प्रारंभ के साथ एक चर की परिभाषा का उपयोग कर सकते हैं <code>auto</code> कीवर्ड।<ref>{{cite web |url=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1478.pdf |author1=Jaakko Järvi |author2=Bjarne Stroustrup |author3=Douglas Gregor |author4=Jeremy Siek |title=Decltype and auto, Programming Language C++, Document no: N1478=03-0061 |date=April 28, 2003 |access-date=June 6, 2015 |archive-date=May 28, 2015 |archive-url=https://web.archive.org/web/20150528112722/http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1478.pdf |url-status=live }}</ref><ref>{{cite web|url=http://accu.org/index.php/journals/1859|title="Auto – A Necessary Evil?" Overload Journal #115|author=Roger Orr|date=June 2013|access-date=2015-06-06|archive-date=2015-06-06|archive-url=https://web.archive.org/web/20150606155637/http://accu.org/index.php/journals/1859|url-status=live}}</ref> यह विशिष्ट प्रकार के प्रारंभकर्ता का एक चर बनाता है:
Line 222: Line 222:
ऑटो अन्य_वैरिएबल = 5;
ऑटो अन्य_वैरिएबल = 5;


के जैसा <code>some_strange_callable_type</code> बस वह है जो विशेष टेम्प्लेट फ़ंक्शन ओवरराइड करता है <code>std::bind</code> उन विशेष तर्कों के लिए रिटर्न। इस प्रकार को संकलक द्वारा अपने सिमेंटिक विश्लेषण कर्तव्यों के भाग के रूप में आसानी से निर्धारित किया जाता है, लेकिन उपयोगकर्ता के लिए निरीक्षण पर निर्धारित करना आसान नहीं है।
के जैसा <code>some_strange_callable_type</code> बस वह है जो विशेष टेम्प्लेट फ़ंक्शन ओवरराइड करता है <code>std::bind</code> उन विशेष तर्कों के लिए रिटर्न। इस प्रकार को संकलक द्वारा अपने सिमेंटिक विश्लेषण कर्तव्यों के भाग के रूप में सरली से निर्धारित किया जाता है, लेकिन उपयोगकर्ता के लिए निरीक्षण पर निर्धारित करना सरल नहीं है।
के जैसा <code>other_variable</code> भी अच्छी तरह से परिभाषित है, लेकिन उपयोगकर्ता के लिए यह निर्धारित करना आसान है। यह है एक <code>int</code>, जो पूर्णांक शाब्दिक के समान प्रकार है।
के जैसा <code>other_variable</code> भी अच्छी तरह से परिभाषित है, लेकिन उपयोगकर्ता के लिए यह निर्धारित करना सरल है। यह है एक <code>int</code>, जो पूर्णांक शाब्दिक के समान प्रकार है।


यह कीवर्ड का उपयोग <code>auto</code> सी ++ में इस कीवर्ड के शब्दार्थ का पुन: उपयोग किया जाता है, जो मूल रूप से टाइपलेस पूर्ववर्ती भाषा बी (प्रोग्रामिंग लैंग्वेज) में उपयोग किया गया था # एक अनपेक्षित [[स्वचालित चर]] परिभाषा को दर्शाने की संबंधित भूमिका में उदाहरण।
यह कीवर्ड का उपयोग <code>auto</code> सी ++ में इस कीवर्ड के शब्दार्थ का पुन: उपयोग किया जाता है, जो मूल रूप से टाइपलेस पूर्ववर्ती भाषा बी (प्रोग्रामिंग लैंग्वेज) में उपयोग किया गया था # एक अनपेक्षित [[स्वचालित चर]] परिभाषा को दर्शाने की संबंधित भूमिका में उदाहरण।
Line 265: Line 265:


==== लूप के लिए रेंज आधारित ====
==== लूप के लिए रेंज आधारित ====
C++11 के सिंटैक्स का विस्तार करता है <code>for</code> तत्वों की एक श्रृंखला पर आसान पुनरावृत्ति की अनुमति देने के लिए कथन:
C++11 के सिंटैक्स का विस्तार करता है <code>for</code> तत्वों की एक श्रृंखला पर सरल पुनरावृत्ति की अनुमति देने के लिए कथन:


int my_array [5] = {1, 2, 3, 4, 5};
int my_array [5] = {1, 2, 3, 4, 5};

Revision as of 20:01, 18 March 2023

C++11, C++ प्रोग्रामिंग भाषा के लिए मानकीकरण के लिए अंतर्राष्ट्रीय संगठन/अंतर्राष्ट्रीय इंटरनेशनल इलेक्ट्रोटेक्नीकल कमीशन मानक का एक संस्करण है। C++ 11 ने C++ मानक के पूर्व संस्करण को बदल दिया, जिसे C++ 03 कहा जाता है,[1] और बाद में इसे C++14 से बदल दिया गया। नाम विनिर्देश के प्रकाशन वर्ष द्वारा भाषा संस्करणों के नामकरण की परंपरा का पालन करता है, चूंकि इसे पूर्व में C++0x नाम दिया गया था क्योंकि यह 2010 से पहले प्रकाशित होने की उम्मीद थी।[2] यद्यपि डिज़ाइन लक्ष्यों में से एक मुख्य भाषा में परिवर्तनों पर लाइब्रेरी में परिवर्तनों को प्राथमिकता देना था,[3] C++ 11 मूल भाषा में कई बदलाव करता है। कोर लैंग्वेज के जिन क्षेत्रों में ज्यादा सुधार हुआ उनमें मल्टीथ्रेडिंग सपोर्ट, सामान्य प्रोग्रामिंग सपोर्ट, यूनिफॉर्म इनिशियलाइज़ेशन और परफॉर्मेंस सम्मिलित हैं। गणितीय विशेष कार्यों के लाइब्रेरी को छोड़कर, C++ मानक लाइब्रेरी में भी महत्वपूर्ण परिवर्तन किए गए, जिसमें अधिकांश C++ तकनीकी रिपोर्ट 1 (TR1) लाइब्रेरी (कंप्यूटर विज्ञान) सम्मिलित थे।[4] C++11 को ISO/IEC 14882:2011 के रूप में प्रकाशित किया गया था[5] सितंबर 2011 में और शुल्क के लिए उपलब्ध है। प्रकाशित C++11 मानक के समान कार्य करने वाला मसौदा N3337 है, दिनांक 16 जनवरी 2012;[6] इसमें C++11 मानक से केवल संपादकीय सुधार हैं।[7]

डिजाइन लक्ष्य

डिज़ाइन समिति ने C++11 को डिज़ाइन करने में कई लक्ष्यों पर टिके रहने का प्रयास किया:

  • ISO/IEC 14882|C++98 और संभवतः C (प्रोग्रामिंग भाषा) के साथ स्थिरता और अनुकूलता बनाए रखें
  • मूल भाषा का विस्तार करने के बजाय मानक लाइब्रेरी के माध्यम से नई सुविधाओं को प्रस्तुत करना पसंद करें
  • उन बदलावों को प्राथमिकता दें जो प्रोग्रामिंग तकनीक को विकसित कर सकें
  • केवल विशिष्ट अनुप्रयोगों के लिए उपयोगी नई सुविधाओं को पेश करने के बजाय सिस्टम और लाइब्रेरी डिज़ाइन को सुविधाजनक बनाने के लिए C++ में सुधार करें
  • पहले की असुरक्षित तकनीकों के सुरक्षित विकल्प प्रदान करके प्रकार की सुरक्षा बढ़ाएँ
  • प्रदर्शन और सीधे हार्डवेयर के साथ कार्य करने की क्षमता बढ़ाएँ
  • वास्तविक दुनिया की समस्याओं के लिए उचित समाधान प्रदान करें
  • शून्य-ओवरहेड सिद्धांत लागू करें (कुछ उपयोगिताओं द्वारा आवश्यक अतिरिक्त समर्थन का उपयोग तभी किया जाना चाहिए जब उपयोगिता का उपयोग किया जाता है)
  • विशेषज्ञ प्रोग्रामरों द्वारा आवश्यक किसी भी उपयोगिता को हटाए बिना सी ++ को पढ़ाने और सीखने में सरल बनाएं

शुरुआती लोगों पर ध्यान देना महत्वपूर्ण माना जाता है, क्योंकि अधिकांश कंप्यूटर प्रोग्रामर सदैव ऐसे ही होते हैं, और क्योंकि कई शुरुआती अपने ज्ञान को कभी भी विस्तृत नहीं करते हैं, खुद को उस भाषा के पहलुओं में कार्य करने के लिए सीमित करते हैं जिसमें वे विशेषज्ञ होते हैं।[1]

C++ कोर भाषा के लिए एक्सटेंशन

C++ समिति का एक कार्य भाषा कोर का विकास है। कोर लैंग्वेज के जिन क्षेत्रों में ज्यादा सुधार हुआ उनमें थ्रेड (कंप्यूटर साइंस) सपोर्ट, जेनेरिक प्रोग्रामिंग सपोर्ट, यूनिफॉर्म इनिशियलाइज़ेशन और परफॉर्मेंस सम्मिलित हैं।

कोर लैंग्वेज रनटाइम परफॉरमेंस एन्हांसमेंट

ये भाषा सुविधाएँ मुख्य रूप से स्मृति या कम्प्यूटेशनल गति के किसी प्रकार के प्रदर्शन लाभ प्रदान करने के लिए सम्मिलित हैं।

रेवल्यू रेफरेंस और मूव कंस्ट्रक्टर्स

C ++ 03 (और पहले) में, अस्थायी (मूल्य (कंप्यूटर विज्ञान) कहा जाता है, क्योंकि वे अक्सर असाइनमेंट के दाहिने तरफ झूठ बोलते हैं) का उद्देश्य कभी भी परिवर्तनीय नहीं होना चाहिए - जैसा कि सी में - और इन्हें अलग-अलग माना जाता है से const T& प्रकार; फिर भी, कुछ मामलों में, टेम्परेरी को संशोधित किया जा सकता था, एक ऐसा व्यवहार जिसे एक उपयोगी बचाव का रास्ता भी माना जाता था।[8] C++11 एक नया गैर-कॉन्स्ट संदर्भ प्रकार (C++) जोड़ता है जिसे a कहा जाता है। rvalue reference, द्वारा पहचाना गया T&&. यह उन अस्थायी वस्तुओं को संदर्भित करता है जिन्हें चलने वाले शब्दार्थों की अनुमति देने के उद्देश्य से आरंभिक होने के बाद संशोधित करने की अनुमति दी जाती है।

सी ++ 03 के साथ एक पुरानी प्रदर्शन समस्या महंगी और अनावश्यक गहरी प्रतिलिपि है जो वस्तुओं को मूल्य से पारित होने पर अंतर्निहित रूप से हो सकती है। इस मुद्दे को स्पष्ट करने के लिए, विचार करें कि a std::vector<T> आंतरिक रूप से, परिभाषित आकार के साथ सी-शैली सरणी के चारों ओर एक आवरण है। यदि एक std::vector<T> अस्थायी बनाया जाता है या किसी फ़ंक्शन से लौटाया जाता है, इसे केवल एक नया बनाकर संग्रहीत किया जा सकता है std::vector<T> और इसमें सभी रावल्यू के डेटा को कॉपी करना। तब अस्थायी और उसकी सारी स्मृति नष्ट हो जाती है। (सरलता के लिए, यह चर्चा वापसी मूल्य अनुकूलन की उपेक्षा करती है।)

C++11 में, ab:More C++ Idioms/Move Constructor|move constructorका std::vector<T> जो एक के लिए एक प्रतिद्वंद्विता संदर्भ लेता है std::vector<T> नए में रावल्यू से आंतरिक सी-शैली सरणी में पॉइंटर को कॉपी कर सकते हैं std::vector<T>, फिर पॉइंटर को रावल्यू के अंदर शून्य पर सेट करें। चूंकि अस्थायी का फिर से उपयोग नहीं किया जाएगा, कोई भी कोड अशक्त सूचक तक पहुंचने का प्रयास नहीं करेगा, और क्योंकि सूचक शून्य है, जब यह दायरे से बाहर हो जाता है तो इसकी मेमोरी को हटाया नहीं जाता है। इसलिए, ऑपरेशन न केवल एक गहरी प्रतिलिपि की कीमत चुकाता है, बल्कि सुरक्षित और अदृश्य है।

मानक लाइब्रेरी के बाहर कोई बदलाव करने की आवश्यकता के बिना रेवल्यू संदर्भ मौजूदा कोड को प्रदर्शन लाभ प्रदान कर सकते हैं। एक लौटाने वाले फ़ंक्शन के दिए गए मान का प्रकार std::vector<T> अस्थायी को स्पष्ट रूप से बदलने की आवश्यकता नहीं है std::vector<T> && मूव कंस्ट्रक्टर को आमंत्रित करने के लिए, क्योंकि अस्थायी रूप से स्वचालित रूप से प्रतिद्वंद्विता माना जाता है। (चूंकि, यदि std::vector<T> एक सी ++ 03 संस्करण है जिसमें एक चालक कन्स्ट्रक्टर नहीं है, तो कॉपी कन्स्ट्रक्टर को एक के साथ बुलाया जाएगा const std::vector<T>&, एक महत्वपूर्ण मेमोरी आवंटन के कारण।)

सुरक्षा कारणों से कुछ प्रतिबंध लगाए गए हैं। एक नामांकित चर को कभी भी प्रतिद्वंद्विता नहीं माना जाएगा, भले ही इसे इस तरह घोषित किया गया हो। एक प्रतिद्वंद्विता प्राप्त करने के लिए, फ़ंक्शन Template std::move() उपयोग किया जाना चाहिए। रावल्यू संदर्भों को केवल कुछ परिस्थितियों में ही संशोधित किया जा सकता है, जिसका मुख्य रूप से मूव कंस्ट्रक्टर के साथ उपयोग करने का इरादा है।

रावल्यू संदर्भों के शब्दों की प्रकृति के कारण, और लैवल्यू संदर्भों (नियमित संदर्भों) के शब्दों में कुछ संशोधन के कारण, रैवल्यू संदर्भ डेवलपर्स को सही फ़ंक्शन अग्रेषण प्रदान करने की अनुमति देते हैं। जब #Variadic टेम्पलेट्स के साथ जोड़ा जाता है, तो यह क्षमता फ़ंक्शन टेम्पलेट्स के लिए अनुमति देती है जो तर्कों को किसी अन्य फ़ंक्शन पर पूरी तरह से अग्रेषित कर सकते हैं जो उन विशेष तर्कों को लेता है। यह कन्स्ट्रक्टर पैरामीटर को अग्रेषित करने के लिए सबसे उपयोगी है, फैक्ट्री फ़ंक्शंस बनाने के लिए जो स्वचालित रूप से उन विशेष तर्कों के लिए सही कन्स्ट्रक्टर को कॉल करेगा। इसे emplace_back C++ मानक लाइब्रेरी विधियों के सेट में देखा जा सकता है।

constexpr - सामान्यीकृत स्थिर भाव

सी ++ में सदैव निरंतर अभिव्यक्ति की अवधारणा होती है। ये ऐसे भाव हैं 3+4 वह सदैव एक ही परिणाम देगा, संकलन समय और रन टाइम पर। लगातार अभिव्यक्तियाँ संकलक के लिए अनुकूलन के अवसर हैं, और संकलक अक्सर संकलन-समय फ़ंक्शन निष्पादन और कार्यक्रम में परिणामों को हार्डकोड करते हैं। साथ ही, कई स्थानों पर, C++ विनिर्देशन के लिए निरंतर व्यंजकों का उपयोग करने की आवश्यकता होती है। एक सरणी को परिभाषित करने के लिए निरंतर अभिव्यक्ति की आवश्यकता होती है, और गणनाकर्ता मान निरंतर अभिव्यक्ति होना चाहिए।

चूंकि, एक निरंतर अभिव्यक्ति को फ़ंक्शन कॉल या ऑब्जेक्ट कन्स्ट्रक्टर रखने की अनुमति नहीं दी गई है। तो कोड का एक टुकड़ा जितना सरल है उतना ही अमान्य है:

int get_five() {वापसी 5;}

int some_value [get_five() + 7]; // 12 पूर्णांकों की एक सरणी बनाएँ। खराब गठित सी ++

यह सी ++ 03 में मान्य नहीं था, क्योंकि get_five() + 7 स्थिर अभिव्यक्ति नहीं है। सी ++ 03 कंपाइलर के पास यह जानने का कोई तरीका नहीं है कि क्या get_five() वास्तव में रनटाइम पर स्थिर है। सिद्धांत रूप में, यह फ़ंक्शन वैश्विक चर को प्रभावित कर सकता है, अन्य गैर-रनटाइम स्थिर कार्यों आदि को कॉल कर सकता है।

C++11 ने कीवर्ड पेश किया constexpr, जो उपयोगकर्ता को यह गारंटी देने की अनुमति देता है कि एक फ़ंक्शन या ऑब्जेक्ट कंस्ट्रक्टर एक संकलन-समय स्थिरांक है।[9] उपरोक्त उदाहरण को निम्नानुसार फिर से लिखा जा सकता है:

constexpr int get_five () {वापसी 5;}

int some_value [get_five() + 7]; // 12 पूर्णांकों की एक सरणी बनाएँ। वैध सी ++ 11

यह संकलक को समझने और सत्यापित करने की अनुमति देता है get_five() एक संकलन-समय स्थिरांक है।

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

C++11 से पहले, वेरिएबल्स के मानों को निरंतर एक्सप्रेशंस में उपयोग किया जा सकता है, अगर वेरिएबल्स को कॉन्स घोषित किया जाता है, एक इनिशियलाइज़र होता है जो एक कॉन्स्टेंट एक्सप्रेशन होता है, और इंटीग्रल या एन्यूमरेशन टाइप का होता है। सी ++ 11 प्रतिबंध को हटा देता है कि वेरिएबल्स अभिन्न या गणना प्रकार के होने चाहिए यदि उन्हें परिभाषित किया गया है constexpr कीवर्ड:

constexpr डबल अर्थ_गुरुत्वाकर्षण_त्वरण = 9.8;

constexpr दोहरा चाँद_गुरुत्वाकर्षण_त्वरण = पृथ्वी_गुरुत्वाकर्षण_त्वरण / 6.0;

इस प्रकार के डेटा वेरिएबल्स निहित रूप से हैं, और एक इनिशियलाइज़र होना चाहिए जो एक निरंतर अभिव्यक्ति होना चाहिए।

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

किसी भी प्रकार के लिए कॉपी कन्स्ट्रक्टर constexpr कंस्ट्रक्टर्स को आमतौर पर एक के रूप में भी परिभाषित किया जाना चाहिए constexpr कन्स्ट्रक्टर, प्रकार की वस्तुओं को कॉन्स्टैक्स फ़ंक्शन से मूल्य द्वारा वापस करने की अनुमति देने के लिए। किसी वर्ग का कोई भी सदस्य कार्य, जैसे कॉपी कंस्ट्रक्टर, ऑपरेटर ओवरलोड, आदि को घोषित किया जा सकता है constexpr, जब तक वे constexpr कार्यों के लिए आवश्यकताओं को पूरा करते हैं। यह संकलक को संकलन समय पर वस्तुओं की प्रतिलिपि बनाने, उन पर संचालन करने आदि की अनुमति देता है।

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

constexpr से मतभेद होना consteval, सी ++ 20 में पेश किया गया, जिसमें बाद वाले को सदैव एक संकलन समय स्थिरांक उत्पन्न करना चाहिए, जबकि constexpr यह प्रतिबंध नहीं है।

सादे पुराने डेटा की परिभाषा में संशोधन

सी ++ 03 में, एक वर्ग या संरचना को सादे पुराने डेटा (पीओडी) प्रकार के रूप में माना जाने के लिए कई नियमों का पालन करना चाहिए। इस परिभाषा में फिट होने वाले प्रकार सी के साथ संगत ऑब्जेक्ट लेआउट उत्पन्न करते हैं, और उन्हें स्थिर रूप से प्रारंभ भी किया जा सकता है। C++ 03 मानक में प्रतिबंध है कि कौन से प्रकार C के साथ संगत हैं या कोई तकनीकी कारण नहीं होने के बावजूद स्थिर रूप से आरंभ किया जा सकता है, एक संकलक प्रोग्राम को स्वीकार नहीं कर सकता; अगर किसी को C++03 POD प्रकार बनाना था और एक गैर-वर्चुअल सदस्य फ़ंक्शन जोड़ना था, तो यह प्रकार अब POD प्रकार नहीं होगा, स्थिर रूप से आरंभ नहीं किया जा सकता है, और मेमोरी लेआउट में कोई बदलाव नहीं होने के बावजूद C के साथ असंगत होगा .

सी ++ 11 ने पीओडी अवधारणा को दो अलग-अलग अवधारणाओं में विभाजित करके कई पीओडी नियमों को आराम दिया: तुच्छ और मानक-लेआउट।

एक प्रकार जो तुच्छ है, उसे स्टैटिकली इनिशियलाइज़ किया जा सकता है। इसका अर्थ यह भी है कि इसके माध्यम से डेटा को कॉपी करना मान्य है memcpyकॉपी कन्स्ट्रक्टर का उपयोग करने के बजाय। तुच्छ प्रकार का जीवनकाल तब शुरू होता है जब इसका भंडारण परिभाषित किया जाता है, न कि जब कोई निर्माणकर्ता पूरा हो जाता है।

एक तुच्छ वर्ग या संरचना को एक के रूप में परिभाषित किया गया है:

  1. एक मामूली डिफ़ॉल्ट कन्स्ट्रक्टर है। यह #स्पष्ट रूप से डिफॉल्ट किए गए विशेष सदस्य फ़ंक्शन का उपयोग कर सकता है (SomeConstructor() = default;).
  2. ट्रिवियल कॉपी और मूव कंस्ट्रक्टर हैं, जो डिफॉल्ट सिंटैक्स का उपयोग कर सकते हैं।
  3. ट्रिवियल कॉपी और मूव असाइनमेंट ऑपरेटर हैं, जो डिफ़ॉल्ट सिंटैक्स का उपयोग कर सकते हैं।
  4. एक तुच्छ विध्वंसक है, जो आभासी नहीं होना चाहिए।

कंस्ट्रक्टर केवल तभी तुच्छ होते हैं जब कक्षा का कोई आभासी सदस्य कार्य न हो और कोई आभासी आधार वर्ग न हो। कॉपी/मूव ऑपरेशंस के लिए भी सभी गैर-स्थैतिक डेटा सदस्यों को तुच्छ होने की आवश्यकता होती है।

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

  1. इसका कोई आभासी कार्य नहीं है
  2. इसका कोई वर्चुअल बेस क्लास नहीं है
  3. इसके सभी गैर-स्थैतिक डेटा सदस्यों का एक ही अभिगम नियंत्रण (सार्वजनिक, निजी, संरक्षित) है
  4. इसके सभी गैर-स्थैतिक डेटा सदस्य, इसके आधार वर्ग में कोई भी सम्मिलित है, पदानुक्रम में एक ही वर्ग में हैं
  5. उपरोक्त नियम सभी आधार वर्गों और वर्ग पदानुक्रम में सभी गैर-स्थैतिक डेटा सदस्यों पर भी लागू होते हैं
  6. इसमें पहले परिभाषित गैर-स्थैतिक डेटा सदस्य के समान प्रकार का कोई आधार वर्ग नहीं है

एक वर्ग / संरचना / संघ को POD माना जाता है यदि यह तुच्छ, मानक-लेआउट है, और इसके सभी गैर-स्थैतिक डेटा सदस्य और आधार वर्ग POD हैं।

इन अवधारणाओं को अलग करके, दूसरे को खोए बिना एक को छोड़ना संभव हो जाता है। जटिल मूव और कॉपी कंस्ट्रक्टर वाला एक वर्ग तुच्छ नहीं हो सकता है, लेकिन यह मानक-लेआउट हो सकता है और इस प्रकार सी के साथ इंटरऑपरेट कर सकता है। इसी तरह, सार्वजनिक और निजी गैर-स्थैतिक डेटा सदस्यों वाला एक वर्ग मानक-लेआउट नहीं होगा, लेकिन यह हो सकता है तुच्छ और इस प्रकार memcpy-योग्य।

कोर लैंग्वेज बिल्ड-टाइम परफॉर्मेंस एन्हांसमेंट

बाहरी टेम्पलेट

सी ++ 03 में, जब भी अनुवाद इकाई में पूरी तरह से निर्दिष्ट टेम्पलेट का सामना करना पड़ता है तो संकलक को टेम्पलेट को तुरंत चालू करना चाहिए। यदि टेम्पलेट को कई अनुवाद इकाइयों में एक ही प्रकार के साथ तत्काल किया जाता है, तो यह नाटकीय रूप से संकलन समय बढ़ा सकता है। C++ 03 में इसे रोकने का कोई तरीका नहीं है, इसलिए C++11 ने बाहरी डेटा घोषणाओं के अनुरूप बाहरी टेम्पलेट घोषणाएं पेश कीं।

सी ++ 03 में यह वाक्यविन्यास है कि संकलक को टेम्पलेट को तुरंत चालू करने के लिए बाध्य किया जाए:

टेम्पलेट वर्ग एसटीडी:: वेक्टर

C++11 अब यह सिंटैक्स प्रदान करता है:

बाहरी टेम्पलेट वर्ग एसटीडी:: वेक्टर

जो संकलक को इस अनुवाद इकाई में टेम्पलेट को तत्काल नहीं करने के लिए कहता है।

कोर भाषा प्रयोज्य संवर्द्धन

भाषा को उपयोग में सरल बनाने के प्राथमिक उद्देश्य के लिए ये सुविधाएं सम्मिलित हैं। ये प्रकार की सुरक्षा में सुधार कर सकते हैं, कोड पुनरावृत्ति को कम कर सकते हैं, गलत कोड की संभावना कम कर सकते हैं, आदि।

प्रारंभकर्ता सूचियां

सी ++ 03 ने सी से प्रारंभकर्ता-सूची सुविधा को विरासत में मिला है। संरचना में सदस्यों की परिभाषाओं के क्रम में एक संरचना या सरणी को ब्रेसिज़ में तर्कों की एक सूची दी जाती है। ये इनिशियलाइज़र-सूचियाँ पुनरावर्ती हैं, इसलिए अन्य स्ट्रक्चर वाले स्ट्रक्चर या स्ट्रक्चर का एक सरणी उनका उपयोग कर सकता है।

संरचना वस्तु {

   पहले तैरना;
   इंट सेकंड;

};

वस्तु अदिश = {0.43f, 10}; // एक वस्तु, पहले = 0.43f और दूसरी = 10 के साथ ऑब्जेक्ट ऐरे [] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; // तीन वस्तुओं की एक सरणी

यह स्थैतिक सूचियों के लिए बहुत उपयोगी है, या किसी संरचना को कुछ मूल्य के लिए आरंभ करना है। सी ++ किसी ऑब्जेक्ट को प्रारंभ करने के लिए कन्स्ट्रक्टर भी प्रदान करता है, लेकिन वे अक्सर प्रारंभिक सूची के रूप में सुविधाजनक नहीं होते हैं। चूंकि, सी ++ 03 प्रारंभिक-सूचियों को केवल उन संरचनाओं और कक्षाओं पर अनुमति देता है जो सादा पुराने डेटा (पीओडी) परिभाषा के अनुरूप हैं; सी ++ 11 प्रारंभकर्ता-सूचियों को बढ़ाता है, इसलिए इन्हें मानक कंटेनर समेत सभी वर्गों के लिए उपयोग किया जा सकता है std::vector.

C++11 अवधारणा को एक टेम्प्लेट से बांधता है, जिसे कहा जाता है std::initializer_list. यह कंस्ट्रक्टर्स और अन्य फ़ंक्शंस को इनिशियलाइज़र-सूचियों को पैरामीटर के रूप में लेने की अनुमति देता है। उदाहरण के लिए:

क्लास सीक्वेंस क्लास { जनता:

   अनुक्रम क्लास (एसटीडी :: प्रारंभकर्ता_सूची <int> सूची);

};

यह अनुमति देता है SequenceClass पूर्णांकों के अनुक्रम से निर्मित होना, जैसे:

सीक्वेंस क्लास some_var = {1, 4, 5, 6};

यह कंस्ट्रक्टर एक विशेष प्रकार का कंस्ट्रक्टर है, जिसे इनिशियलाइज़र-लिस्ट-कन्स्ट्रक्टर कहा जाता है। ऐसे कन्स्ट्रक्टर वाले वर्गों को विशेष रूप से वर्दी प्रारंभिकरण के दौरान माना जाता है (देखें # वर्दी प्रारंभिकरण)

टेम्पलेट वर्ग std::initializer_list<> एक प्रथम श्रेणी का नागरिक है | प्रथम श्रेणी का C++11 मानक लाइब्रेरी प्रकार। वे C++11 कंपाइलर के उपयोग के माध्यम से स्थिर रूप से निर्मित किए जा सकते हैं {} ऐसे संदर्भों में एक प्रकार के नाम के बिना सिंटैक्स जहां ऐसे ब्रेसिज़ a को घटाएंगे std::initializer_list, या जैसे प्रकार को स्पष्ट रूप से निर्दिष्ट करके std::initializer_list<SomeType>{args} (और इसी तरह निर्माण सिंटैक्स की अन्य किस्मों के लिए)।

सूची को एक बार बनाने के बाद कॉपी किया जा सकता है, जो सस्ता है और कॉपी-दर-संदर्भ के रूप में कार्य करेगा (वर्ग आमतौर पर प्रारंभ/अंत पॉइंटर्स की एक जोड़ी के रूप में कार्यान्वित किया जाता है)। एक std::initializer_list स्थिर है: एक बार इसके सदस्यों को बनाया जाने के बाद बदला नहीं जा सकता है, और न ही उन सदस्यों में डेटा बदला जा सकता है (जो उनसे आगे बढ़ने से नियम बनाते हैं, कक्षा के सदस्यों में प्रतियों की आवश्यकता होती है, आदि)।

यद्यपि इसका निर्माण विशेष रूप से संकलक द्वारा किया जाता है, a std::initializer_list एक वास्तविक प्रकार है, और इसलिए इसका उपयोग क्लास कंस्ट्रक्टर के अलावा अन्य स्थानों पर भी किया जा सकता है। नियमित कार्य टाइप किए जा सकते हैं std::initializer_listएस तर्क के रूप में। उदाहरण के लिए:

शून्य function_name (एसटीडी :: प्रारंभकर्ता_सूची <फ्लोट> सूची); // नकल करना सस्ता है; ऊपर देखें

function_name ({1.0f, -3.45f, -0.4f});

मानक लाइब्रेरी में इसके उदाहरणों में सम्मिलित हैं std::min() और std::max() टेम्पलेट्स ले रहा है std::initializer_listसंख्यात्मक प्रकार का।

मानक कंटेनरों को इन तरीकों से भी आरंभ किया जा सकता है:

एसटीडी :: वेक्टर <एसटीडी :: स्ट्रिंग> वी = {xyzzy, प्लग, abracadabra}; एसटीडी :: वेक्टर <एसटीडी :: स्ट्रिंग> वी ({xyzzy, प्लग, abracadabra}); एसटीडी :: वेक्टर <एसटीडी :: स्ट्रिंग> वी {xyzzy, प्लग, abracadabra}; // नीचे यूनिफ़ॉर्म इनिशियलाइज़ेशन देखें

यूनिफ़ॉर्म इनिशियलाइज़ेशन

सी ++ 03 में प्रारंभिक प्रकारों के साथ कई समस्याएं हैं। ऐसा करने के कई तरीके सम्मिलित हैं, और कुछ परस्पर विनिमय करने पर अलग-अलग परिणाम देते हैं। उदाहरण के लिए, पारंपरिक कन्स्ट्रक्टर सिंटैक्स, फ़ंक्शन घोषणा की तरह दिख सकता है, और यह सुनिश्चित करने के लिए कदम उठाए जाने चाहिए कि संकलक का सबसे परेशान पार्स नियम इस तरह की गलती नहीं करेगा। केवल समुच्चय और POD प्रकारों को कुल प्रारंभकर्ताओं के साथ प्रारंभ किया जा सकता है (का उपयोग करके SomeType var = {/*stuff*/};).

C++11 एक सिंटैक्स प्रदान करता है जो किसी भी वस्तु पर कार्य करने वाले पूरी तरह से समान प्रकार के इनिशियलाइज़ेशन की अनुमति देता है। यह प्रारंभकर्ता सूची सिंटैक्स पर फैलता है:

स्ट्रक्चर बेसिकस्ट्रक्चर {

   इंट एक्स;
   डबल वाई;

};

संरचना AltStruct {

   AltStruct(int x, डबल y)
       : x_{x}
       , Y y}
   {}

निजी:

   इंट x_;
   डबल वाई_;

};

बेसिक स्ट्रक्चर var1{5, 3.2}; AltStruct var2{2, 4.3};

का आरंभीकरण var1 व्यवहार करता है जैसे कि यह कुल-प्रारंभिकरण था। यही है, किसी ऑब्जेक्ट के प्रत्येक डेटा सदस्य, बदले में, प्रारंभकर्ता-सूची से संबंधित मान के साथ प्रतिलिपि-प्रारंभिक किया जाएगा। जहां आवश्यक हो वहां निहित प्रकार के रूपांतरण का उपयोग किया जाएगा। यदि कोई रूपांतरण सम्मिलित नहीं है, या केवल एक संकुचित रूपांतरण सम्मिलित है, तो प्रोग्राम खराब रूप से बना हुआ है। का आरंभीकरण var2 कंस्ट्रक्टर को आमंत्रित करता है।

कोई यह भी कर सकता है:


संरचना IdString {

   एसटीडी :: स्ट्रिंग नाम;
   इंट पहचानकर्ता;

};

आईडीस्ट्रिंग get_string () {

   वापसी {फू, 42}; // स्पष्ट प्रकार की कमी पर ध्यान दें।

}

यूनिफ़ॉर्म इनिशियलाइज़ेशन कंस्ट्रक्टर सिंटैक्स को प्रतिस्थापित नहीं करता है, जिसकी अभी भी कई बार आवश्यकता होती है। यदि किसी वर्ग में प्रारंभकर्ता सूची कन्स्ट्रक्टर है (TypeName(initializer_list<SomeType>);), तो यह निर्माण के अन्य रूपों पर प्राथमिकता लेता है, बशर्ते प्रारंभकर्ता सूची अनुक्रम कन्स्ट्रक्टर के प्रकार के अनुरूप हो। सी ++ 11 का संस्करण std::vector इसके टेम्पलेट प्रकार के लिए प्रारंभकर्ता सूची कन्स्ट्रक्टर है। इस प्रकार यह कोड:

एसटीडी :: वेक्टर <int> the_vec {4};

इनिशियलाइज़र लिस्ट कंस्ट्रक्टर को कॉल करेगा, न कि कंस्ट्रक्टर को std::vector जो एक आकार पैरामीटर लेता है और उस आकार के साथ वेक्टर बनाता है। बाद वाले कंस्ट्रक्टर तक पहुंचने के लिए, उपयोगकर्ता को सीधे मानक कंस्ट्रक्टर सिंटैक्स का उपयोग करने की आवश्यकता होगी।

टाइप अनुमान

सी ++ 03 (और सी) में, एक चर का उपयोग करने के लिए, इसके प्रकार को स्पष्ट रूप से निर्दिष्ट किया जाना चाहिए। चूंकि, टेम्प्लेट प्रकार और टेम्प्लेट मेटाप्रोग्रामिंग तकनीकों के आगमन के साथ, किसी चीज़ का प्रकार, विशेष रूप से किसी फ़ंक्शन का अच्छी तरह से परिभाषित वापसी मूल्य, सरली से व्यक्त नहीं किया जा सकता है। इस प्रकार, इंटरमीडिएट्स को वेरिएबल्स में स्टोर करना मुश्किल है, संभवतः किसी दिए गए मेटाप्रोग्रामिंग लाइब्रेरी के इंटर्नल्स के ज्ञान की आवश्यकता है।

सी ++ 11 इसे दो तरीकों से कम करने की अनुमति देता है। सबसे पहले, एक स्पष्ट प्रारंभ के साथ एक चर की परिभाषा का उपयोग कर सकते हैं auto कीवर्ड।[10][11] यह विशिष्ट प्रकार के प्रारंभकर्ता का एक चर बनाता है:

ऑटो some_strange_callable_type = std::bind(&some_function, _2, _1, some_object); ऑटो अन्य_वैरिएबल = 5;

के जैसा some_strange_callable_type बस वह है जो विशेष टेम्प्लेट फ़ंक्शन ओवरराइड करता है std::bind उन विशेष तर्कों के लिए रिटर्न। इस प्रकार को संकलक द्वारा अपने सिमेंटिक विश्लेषण कर्तव्यों के भाग के रूप में सरली से निर्धारित किया जाता है, लेकिन उपयोगकर्ता के लिए निरीक्षण पर निर्धारित करना सरल नहीं है। के जैसा other_variable भी अच्छी तरह से परिभाषित है, लेकिन उपयोगकर्ता के लिए यह निर्धारित करना सरल है। यह है एक int, जो पूर्णांक शाब्दिक के समान प्रकार है।

यह कीवर्ड का उपयोग auto सी ++ में इस कीवर्ड के शब्दार्थ का पुन: उपयोग किया जाता है, जो मूल रूप से टाइपलेस पूर्ववर्ती भाषा बी (प्रोग्रामिंग लैंग्वेज) में उपयोग किया गया था # एक अनपेक्षित