टेम्पलेट मेटाप्रोग्रामिंग

नमूना मेटाप्रोग्रामिंग टीएमपी एक मापन और संख्यात्मक तकनीक है जिसमें एक संकलक द्वारा अस्थायी स्रोत पारण चिन्ह उत्पन्न करने के लिए सामान्य कार्यक्रम का उपयोग किया जाता है जिसे कंपाइलर द्वारा शेष स्रोत सांकेतिक चिन्ह के साथ विलय कर दिया जाता है और फिर संकलित किया जाता है इन नमूनों के आउटपुट में संकलन समय कंपाइल समय लगातार कार्यक्रम की डेटा संरचना और पूरे समारोह कंप्यूटर विज्ञान में सम्मिलित हो सकते हैं नमूने के उपयोग को संकलन-समय कार्यक्रम निष्पादन  कंपाइल समय को बहुरूपता के रूप में माना जा सकता है इस तकनीक का उपयोग कई भाषाओं में किया जाता है जिनमें से सबसे प्रसिद्ध सी ++ है लेकिन गोल कार्यक्रम भाषा डी कार्यक्रम भाषा शंकु कार्यक्रम भाषा और एक्सएल कार्यक्रम भाषा भी है

नमूना मेटाप्रोग्रामिंग का अर्थ गलती से खोजा गया था कुछ अन्य भाषाएं इसी तरह का समर्थन करती हैं यदि अधिक शक्तिशाली संकलन-समय की सुविधाएं जैसे एलआईएसपी कार्यक्रमिक भाषा मैक्रो कंप्यूटर विज्ञान वाक्य  लेख के बाहर हैं।

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

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

नमूना मेटाप्रोग्राम में कोई अपरिवर्तनीय वस्तु नहीं है अर्थात एक बार प्रारंभ होने के बाद कोई चर मूल्य नहीं बदल सकता है इसलिए नमूना मेटाप्रोग्रामिंग को कार्यात्मक कार्यक्रम के रूप में देखा जा सकता है वास्तव में कई नमूना कार्यान्वयन प्रवाह नियंत्रण को केवल रिकर्सन कंप्यूटर विज्ञान के माध्यम से लागू करते हैं।

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

संकलन-समय वर्ग पीढ़ी
संकलन समय में कार्यक्रम का क्या अर्थ है इसे गुणनखण्ड कार्यक्रम के उदाहरण के साथ चित्रित किया जा सकता है जो गैर नमूने सी ++ में प्रतिवर्तन का उपयोग करके निम्नानुसार लिखा जा सकता है।

अहस्तांक्षरित गुणनखण्ड तथा अहस्ताक्षरित n 	वापसी  n = 0 ? 1 एन *  गुणनखण्ड  एन - 1 है

उपयोग के उदाहरण // गुणनखण्ड 0 से 1 निकलेगा // गुणनखण्ड 4 से 24 निकलेगा।

शाब्दिक 0 और 4 के भाज्य मान को निर्धारित करने के लिए उपरोक्त कोड रन टाइम पर निष्पादित होगा। पुनरावर्तन के लिए अंतिम स्थिति प्रदान करने के लिए टेम्प्लेट मेटाप्रोग्रामिंग और टेम्प्लेट विशेषज्ञता का उपयोग करके, प्रोग्राम में उपयोग किए जाने वाले फैक्टोरियल - उपयोग नहीं किए गए किसी भी फैक्टोरियल को अनदेखा करते हुए - इस कोड द्वारा संकलन समय पर गणना की जा सकती है: उपरोक्त कोड संकलन समय पर शाब्दिक 0 और 4 के भाज्य मान की गणना करता है और परिणामों का उपयोग करता है जैसे कि वे सटीक स्थिरांक थे। इस तरह से टेम्प्लेट का उपयोग करने में सक्षम होने के लिए, कंपाइलर को संकलन समय पर अपने मापदंडों के मूल्य का पता होना चाहिए, जिसमें प्राकृतिक पूर्व शर्त है कि फैक्टोरियल ::मान का उपयोग केवल तभी किया जा सकता है जब X को संकलन समय पर जाना जाता है। दूसरे शब्दों में, X एक स्थिर शाब्दिक या एक स्थिर अभिव्यक्ति होना चाहिए।

सी ++ 11 और सी ++ 20 में, कंपाइलर को कोड निष्पादित करने के लिए constexpr और कॉन्स्टेवल पेश किए गए थे। कॉन्स्टेक्सप्र और कॉन्स्टेवल का उपयोग करके, गैर-टेम्पलेटेड सिंटैक्स के साथ सामान्य पुनरावर्ती फैक्टोरियल परिभाषा का उपयोग किया जा सकता है।

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

दूसरे के रूप में, अधिक महत्वपूर्ण, संकलन-समय लूप अनोलिंग का उदाहरण, टेम्पलेट मेटाप्रोग्रामिंग का उपयोग लंबाई-एन वेक्टर वर्ग बनाने के लिए किया जा सकता है (जहां एन को संकलन समय पर जाना जाता है)। अधिक पारंपरिक लंबाई-एन वेक्टर पर लाभ यह है कि लूप को अनियंत्रित किया जा सकता है, जिसके परिणामस्वरूप बहुत अनुकूलित कोड होता है। एक उदाहरण के रूप में, अतिरिक्त ऑपरेटर पर विचार करें। लंबाई-एन सदिश जोड़ को इस रूप में लिखा जा सकता है जब संकलक ऊपर परिभाषित फ़ंक्शन टेम्पलेट को तुरंत चालू करता है, तो निम्न कोड उत्पन्न हो सकता है:

कंपाइलर का ऑप्टिमाइज़र अनलॉक करने में सक्षम होना चाहिए  लूप क्योंकि टेम्पलेट पैरामीटर   संकलन समय पर स्थिर है।

हालाँकि, सावधानी बरतें और सावधानी बरतें क्योंकि इससे कोड ब्लोट हो सकता है क्योंकि प्रत्येक 'एन' (वेक्टर आकार) के लिए अलग-अलग अनियंत्रित कोड उत्पन्न होगा, जिसके साथ आप तुरंत चलते हैं।

स्थैतिक बहुरूपता
प्रकार बहुरूपता एक सामान्य मानक प्रोग्रामिंग सुविधा है जहां व्युत्पन्न वस्तुओं को उनके मूल वस्तु के उदाहरणों के रूप में उपयोग किया जा सकता है लेकिन जहां व्युत्पन्न वस्तुओं के तरीकों को लागू किया जाएगा, जैसा कि इस कोड में है जहां के सभी आह्वान  विधियाँ सर्वाधिक व्युत्पन्न वर्ग की होंगी। यह गतिशील रूप से बहुरूपी व्यवहार (आमतौर पर) vtable के निर्माण द्वारा प्राप्त किया जाता है। वर्चुअल विधियों के साथ कक्षाओं के लिए वर्चुअल लुक-अप टेबल, टेबल जो रन टाइम पर ट्रैवर्स किए जाते हैं ताकि आह्वान की जाने वाली विधि की पहचान हो सके। इस प्रकार, रन-टाइम बहुरूपता आवश्यक रूप से निष्पादन ओवरहेड (हालांकि आधुनिक आर्किटेक्चर पर ओवरहेड छोटा है) पर जोर देता है।

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

स्टेटिक टेबल जनरेशन
स्थैतिक तालिकाओं का लाभ एक साधारण सरणी अनुक्रमण ऑपरेशन के साथ महंगी गणनाओं का प्रतिस्थापन है (उदाहरण के लिए, लुकअप तालिका देखें)। सी ++ में, संकलन समय पर स्थिर तालिका उत्पन्न करने के एक से अधिक तरीके मौजूद हैं। निम्न सूची रिकर्सिव स्ट्रक्चर्स और विविध टेम्पलेट्स का उपयोग करके एक बहुत ही सरल तालिका बनाने का एक उदाहरण दिखाती है। तालिका का आकार दस है। प्रत्येक मान सूचकांक का वर्ग है।

इसके पीछे विचार यह है कि स्ट्रक्चर हेल्पर पुनरावर्ती रूप से एक संरचना से एक और टेम्पलेट तर्क (इस उदाहरण में INDEX * INDEX के रूप में गणना की गई) के साथ प्राप्त करता है जब तक कि टेम्पलेट की विशेषज्ञता 10 तत्वों के आकार पर पुनरावृत्ति समाप्त नहीं करती। विशेषज्ञता केवल चर तर्क सूची का उपयोग सरणी के तत्वों के रूप में करती है। संकलक निम्नलिखित के समान कोड का उत्पादन करेगा (क्लैंग से लिया गया जिसे -Xclang -ast-print -fsyntax-only कहा जाता है)। चूंकि सी ++ 17 इसे और अधिक आसानी से लिखा जा सकता है:

अधिक परिष्कृत उदाहरण दिखाने के लिए निम्नलिखित सूची में कोड को मूल्य गणना के लिए एक सहायक (अधिक जटिल संगणना की तैयारी में), तालिका विशिष्ट ऑफ़सेट और तालिका मानों के प्रकार के लिए एक टेम्पलेट तर्क के लिए विस्तारित किया गया है (उदाहरण के लिए uint8_t, uint16_t, ...) जिसे C++17 का उपयोग करके इस प्रकार लिखा जा सकता है:

अवधारणाएं
C++20 मानक ने C++ प्रोग्रामर्स को मेटा टेम्पलेट प्रोग्रामिंग, अवधारणाओं के लिए एक नया उपकरण दिया। अवधारणाएँ (C++) प्रोग्रामर को प्रकार के लिए आवश्यकताओं को निर्दिष्ट करने की अनुमति देती हैं, ताकि टेम्पलेट का इन्स्टेन्शियशन संभव हो सके। कंपाइलर उस अवधारणा वाले टेम्पलेट की तलाश करता है जिसकी उच्चतम आवश्यकताएं हैं।

यहाँ टेम्पलेट मेटा प्रोग्रामिंग के साथ हल की गई प्रसिद्ध फ़िज़ बज़ समस्या का एक उदाहरण है।

टेम्प्लेट मेटाप्रोग्रामिंग के लाभ और कमियां

 * कंपाइल-टाइम बनाम एक्ज़ीक्यूशन-टाइम ट्रेडऑफ़: यदि टेम्प्लेट मेटाप्रोग्रामिंग का एक बड़ा उपयोग किया जाता है।
 * सामान्य प्रोग्रामिंग: टेम्प्लेट मेटाप्रोग्रामिंग प्रोग्रामर को आर्किटेक्चर पर ध्यान केंद्रित करने और क्लाइंट कोड द्वारा आवश्यक किसी भी कार्यान्वयन की पीढ़ी को कंपाइलर को सौंपने की अनुमति देता है। इस प्रकार, टेम्प्लेट मेटाप्रोग्रामिंग वास्तव में सामान्य कोड को पूरा कर सकता है, जिससे कोड न्यूनीकरण और बेहतर रखरखाव की सुविधा मिलती है.
 * पठनीयता: C++ 11 से पहले C++ के संबंध में, टेम्पलेट मेटाप्रोग्रामिंग के वाक्य-विन्यास और मुहावरे पारंपरिक C++ प्रोग्रामिंग की तुलना में गूढ़ थे, और टेम्पलेट मेटाप्रोग्राम को समझना बहुत मुश्किल हो सकता है। लेकिन सी ++ 11 से आगे मूल्य गणना मेटाप्रोग्रामिंग के लिए सिंटैक्स कम और कम पठनीयता दंड के साथ सामान्य सी ++ के समान अधिक हो जाता है।

यह भी देखें

 * प्रतिस्थापन विफलता एक त्रुटि नहीं है (SFINAE)
 * मेटाप्रोग्रामिंग
 * preprocessor
 * पैरामीट्रिक बहुरूपता
 * अभिव्यक्ति टेम्पलेट्स
 * वैराडिक टेम्पलेट
 * संकलन-समय फ़ंक्शन निष्पादन

बाहरी संबंध

 * (built using template-metaprogramming)
 * (use STL algorithms easily)
 * (type-safe metaprogramming in Haskell)
 * (template metaprogramming in the D programming language)
 * (type-safe metaprogramming in Haskell)
 * (template metaprogramming in the D programming language)