C++11

From Vigyanwiki

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 कहा जाता है। आर के प्रतिद्वंद्विता संदर्भ, द्वारा पहचाना गया T&& उन अस्थायी वस्तुओं को संदर्भित करता है जिन्हें चलाने वाले शब्दार्थों की अनुमति देने के उद्देश्य से आरंभिक होने के बाद संशोधित करने की अनुमति दी जाती है।

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

C++11 में, ab:More C++ Idioms/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() उपयोग किया जाना चाहिए। आर वैल्यू संदर्भों को केवल कुछ परिस्थितियों में ही संशोधित किया जा सकता है, जिसका मुख्य रूप से मूव कंस्ट्रक्टर के साथ उपयोग करने का प्रमाण है।

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

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

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

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

int get_five() {return 5;} int some_value[get_five() + 7]; // Create an array of 12 integers. Ill-formed C++

यह सी ++ 03 में मान्य नहीं था, क्योंकि get_five() + 7 स्थिर अभिव्यक्ति नहीं है। सी ++ 03 कंपाइलर के पास यह जानने का कोई तरीका नहीं है कि क्या get_five() वास्तव में रनटाइम पर स्थिर है। सैद्धांतिक रूप में यह फ़ंक्शन वैश्विक वैरिएबल को प्रभावित करता हैं, तथा अन्य गैर-रनटाइम स्थिर फंक्शन्स आदि को कॉल कर सकते हैं। C++11 ने constexpr कीवर्ड प्रस्तुत किया, जो उपयोगकर्ता को यह गारंटी देने की अनुमति देता है कि एक फ़ंक्शन या ऑब्जेक्ट कंस्ट्रक्टर संकलन-समय स्थिरांक है।[9] उपरोक्त उदाहरण को निम्नानुसार फिर से लिखा जा सकता है:

constexpr int get_five() {return 5;} int some_value[get_five() + 7]; // Create an array of 12 integers. Valid C++11

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

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

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

constexpr double earth_gravitational_acceleration = 9.8; constexpr double moon_gravitational_acceleration = earth_gravitational_acceleration / 6.0;

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

उपयोगकर्ता परिभाषित प्रकारों से निरंतर अभिव्यक्ति डेटा मान बनाने के लिए कन्स्ट्रक्टर constexpr. a 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. एक तुच्छ विध्वंसक है, जो आभासी नहीं होना चाहिए।

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

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

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

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

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

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

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

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

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

template class std::vector<MyClass>;

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

extern template class std::vector<MyClass>;

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

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

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

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

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

संरचना वस्तु

{

struct Object

{

float first;

int second;

};

Object scalar = {0.43f, 10}; //One Object, with first=0.43f and second=10

Object anArray[] = {{13.4f, 3}, {43.28f, 29}, {5.934f, 17}}; //An array of three Objects

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

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

class SequenceClass
{
public:
    SequenceClass(std::initializer_list<int> list);
}

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

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 स्थिर है, इसके सदस्यों को बनाया जाने के पश्चात परिवर्तित नहीं किया जा सकता है, और न ही उन सदस्यों में डेटा परिवर्तित किया जा सकता है (जो उनसे आगे बढ़ने से नियम बनाते हैं, इस प्रकार class के सदस्यों में प्रतियों की आवश्यकता होती है जिनका उपयोग किया जाता हैं)।

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

void function_name(std::initializer_list<float> list); // Copying is cheap; see above 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 सी ++ में इस कीवर्ड के शब्दार्थ का पुन: उपयोग किया जाता है, जो मूल रूप से टाइपलेस पूर्ववर्ती भाषा बी (प्रोग्रामिंग लैंग्वेज) में उपयोग किया गया था # एक अनपेक्षित स्वचालित वैरियेबल परिभाषा को दर्शाने की संबंधित भूमिका में उदाहरण।

आगे, कीवर्ड decltype संकलन-समय पर अभिव्यक्ति के प्रकार को निर्धारित करने के लिए उपयोग किया जा सकता है। उदाहरण के लिए:

int some_int; decltype (some_int) अन्य_इंटीजर_वेरिएबल = 5;

के साथ मिलकर यह अधिक उपयोगी है auto, क्योंकि auto वैरियेबल का प्रकार केवल संकलक के लिए जाना जाता है। चूंकि, decltype कोड में अभिव्यक्तियों के लिए भी बहुत उपयोगी हो सकता है जो ऑपरेटर ओवरलोडिंग और विशेष प्रकारों का भारी उपयोग करता है।

auto कोड की वाचालता को कम करने के लिए भी उपयोगी है। उदाहरण के लिए, लिखने के अतिरिक्त

for (std::vector<int>::const_iterator itr = myvec.cbegin(); itr != myvec.cend(); ++itr)

प्रोग्रामर छोटे का उपयोग कर सकता है

के लिए (ऑटो आईटीआर = myvec.cbegin (); आईटीआर! = myvec.cend (); ++ आईटीआर)

जिसे और अधिक संकुचित किया जा सकता है क्योंकि myvec पुनरावृत्तियों को प्रारंभ/समाप्त करता है:

के लिए (स्थिरांक ऑटो और x: myvec)

यह अंतर बढ़ता है क्योंकि प्रोग्रामर नेस्ट कंटेनरों को प्रारंभ करता है, चूंकि ऐसे मामलों में typedefकोड की मात्रा कम करने का एक अच्छा तरीका है।

द्वारा दर्शाया गया प्रकार decltype द्वारा निकाले गए प्रकार से भिन्न हो सकते हैं auto.

  1. सम्मिलित <वेक्टर>

मुख्य प्रवेश बिंदु() {

   स्थिरांक एसटीडी :: वेक्टर वी (1);
   ऑटो ए = वी [0]; // a का प्रकार int है
   डिक्लेटाइप (वी [0]) बी = 1; // b का प्रकार const int& है, जिसका रिटर्न प्रकार है
                         // एसटीडी :: वेक्टर <int> :: ऑपरेटर [] (size_type) स्थिरांक
   ऑटो सी = 0; // c का प्रकार int है
   ऑटो डी = सी; // डी में टाइप इंट है
   डिक्लेटाइप (सी) ई; // ई में टाइप इंट है, सी द्वारा नामित इकाई का प्रकार
   decltype ((सी)) एफ = सी; // f का प्रकार int& है, क्योंकि (c) एक लवल्यू है
   डिक्लेटाइप (0) जी; // g का प्रकार int है, क्योंकि 0 एक प्रतिद्वंद्विता है

}

लूप के लिए रेंज आधारित

C++11 के सिंटैक्स का विस्तार करता है for तत्वों की एक श्रृंखला पर सरल पुनरावृत्ति की अनुमति देने के लिए कथन:

int my_array [5] = {1, 2, 3, 4, 5}; // my_array में प्रत्येक तत्व का मान दोगुना करें: के लिए (int और x: my_array)

   एक्स * = 2;

// समान लेकिन सरणी तत्वों के लिए प्रकार अनुमान का भी उपयोग करना के लिए (ऑटो और एक्स: my_array)

   एक्स * = 2;


का यह रूप for, जिसे "श्रेणी-आधारित के लिए" कहा जाता है, सूची में प्रत्येक तत्व पर पुनरावृति करेगा। यह सी-स्टाइल सरणियों, इनिशियलाइज़र सूचियों और किसी भी प्रकार के लिए फंक्शन करेगा begin() और end() इसके लिए परिभाषित फंक्शन जो पुनरावृत्तियों को लौटाते हैं। आरंभ/समाप्त जोड़े वाले सभी मानक लाइब्रेरी कंटेनर श्रेणी-आधारित के लिए कथन के साथ फंक्शन करेंगे।

लैम्ब्डा फ़ंक्शंस और एक्सप्रेशन

C++11 अनाम फंक्शन्स को बनाने की क्षमता प्रदान करता है, जिसे लैम्ब्डा फ़ंक्शन कहा जाता है।[12]

इन्हें निम्नानुसार परिभाषित किया गया है:

[](int x, int y) -> int {वापसी x + y; }

वापसी प्रकार (-> int इस उदाहरण में) जब तक सभी को छोड़ा जा सकता है return भाव एक ही प्रकार लौटाते हैं। एक लैम्ब्डा वैकल्पिक रूप से क्लोजर (कंप्यूटर साइंस) हो सकता है।

वैकल्पिक फ़ंक्शन सिंटैक्स

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

टेम्पलेट <class एलएचएस, class आरएचएस>

 Ret Add_func(const Lhs &lhs, const Rhs &rhs) {return lhs + rhs;} //Ret को lhs+rhs का प्रकार होना चाहिए


प्ररूप Ret जो भी प्रकार का जोड़ है Lhs और Rhs उत्पादन करेंगे। उपरोक्त C++11 की फंक्शनक्षमता के साथ भी decltype, ऐसा नहीं हो सकता:

टेम्पलेट <class एलएचएस, class आरएचएस>

 decltype(lhs+rhs) Add_func(const Lhs &lhs, const Rhs &rhs) {वापसी lhs + rhs;} // C++11 मान्य नहीं है


यह वैध सी ++ नहीं है क्योंकि lhs और rhs अभी तक परिभाषित नहीं किया गया है; वे तब तक वैध पहचानकर्ता नहीं होंगे जब तक कि पार्सर ने बाकी फ़ंक्शन प्रोटोटाइप को पार्स नहीं किया हो।

इसके आसपास फंक्शन करने के लिए, सी ++ 11 ने अनुगामी-रिटर्न-प्रकार के साथ एक नया फ़ंक्शन डिक्लेरेशन सिंटैक्स प्रस्तुत किया:[13]

टेम्पलेट

 ऑटो एडिंग_फंक (स्थिरांक एलएचएस और एलएचएस, स्थिरांक आरएचएस और आरएचएस) -> decltype (एलएचएस + आरएचएस) {वापसी एलएचएस + आरएचएस;}

इस सिंटैक्स का उपयोग अधिक सांसारिक फंक्शन घोषणाओं और परिभाषाओं के लिए किया जा सकता है:

स्ट्रक्वैरियेबल समस्ट्रक्वैरियेबल{

   ऑटो func_name (int x, int y) -> int;

};

ऑटो कुछ संरचना :: func_name (int x, int y) -> int {

   वापसी एक्स + वाई;

}

इस मामले में "ऑटो" कीवर्ड का उपयोग सिंटैक्स का हिस्सा है और सी ++ 11 में स्वचालित प्रकार की कटौती नहीं करता है। चूंकि, C ++ 14 से प्रारंभ होकर, अनुगामी रिटर्न प्रकार को पूरी तरह से हटाया जा सकता है और कंपाइलर रिटर्न प्रकार को स्वचालित रूप से घटा देगा।[14]


वस्तु निर्माण में सुधार

सी ++ 03 में, class के रचनाकारों को उस वर्ग की प्रारंभिक सूची में अन्य कन्स्ट्रक्टरों को कॉल करने की अनुमति नहीं है। प्रत्येक कंस्ट्रक्टर को अपने सभी वर्ग सदस्यों का निर्माण स्वयं करना चाहिए या निम्नानुसार एक सामान्य सदस्य फ़ंक्शन को कॉल करना चाहिए:

क्लास समटाइप { जनता:

   कुछ प्रकार (int new_number)
   {
       निर्माण (नया_नंबर);
   }
   कुछ प्रकार ()
   {
       निर्माण (42);
   }

निजी:

   शून्य निर्माण (int new_number)
   {
       संख्या = नया_नंबर;
   }
   इंट संख्या;

};

बेस क्लास के कंस्ट्रक्टर सीधे व्युत्पन्न classओं के संपर्क में नहीं आ सकते हैं; बेस क्लास कंस्ट्रक्टर उपयुक्त होने पर भी प्रत्येक व्युत्पन्न वर्ग को कंस्ट्रक्टर को लागू करना चाहिए। उन सदस्यों की घोषणा के स्थल पर classओं के गैर-निरंतर डेटा सदस्यों को प्रारंभ नहीं किया जा सकता है। इन्हें केवल एक कंस्ट्रक्टर में इनिशियलाइज़ किया जा सकता है।

C++11 इन सभी समस्याओं का समाधान प्रदान करता है।

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

यह सिंटैक्स इस प्रकार है:

क्लास समटाइप {

   इंट संख्या;

जनता:

   कुछ प्रकार (int new_number): संख्या (new_number) {}
   कुछ प्रकार (): कुछ प्रकार (42) {}

};

ध्यान दें कि, इस मामले में, वही प्रभाव बनाकर हासिल किया जा सकता था new_number एक डिफ़ॉल्ट पैरामीटर। नया सिंटैक्स, चूंकि, इंटरफ़ेस के अतिरिक्त फंक्शनान्वयन में डिफ़ॉल्ट मान (42) को व्यक्त करने की अनुमति देता है - लाइब्रेरी कोड के अनुरक्षकों के लिए एक लाभ क्योंकि फ़ंक्शन पैरामीटर के लिए डिफ़ॉल्ट मान कॉल साइट्स के लिए "बेक्ड इन" हैं, जबकि कन्स्ट्रक्टर प्रतिनिधिमंडल अनुमति देता है लाइब्रेरी का उपयोग करके कोड के पुनर्संकलन के बिना मूल्य को बदला जाना है।

यह एक चेतावनी के साथ