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

From Vigyanwiki

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

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

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

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

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

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

नमूना मेटाप्रोग्रामिंग का उपयोग

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

संकलन-समय वर्ग पीढ़ी

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

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

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

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

नमूना < अहस्तांक्षरित एन > संरचना भाज्य स्थैतिक अहस्तांक्षरित मूल्य = एन भाज्य < एन - 1 : : मूल्य

नमूना < > चित्र गुणनखण्ड <0> में स्थैतिक अहस्ताक्षरित मूल्य = 1 है

संकलन-समय कोड अनुकूलन

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

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

template <int length>
Vector<length>& Vector<length>::operator+=(const Vector<length>& rhs) 
{
    for (int i = 0; i < length; ++i)
        value[i] += rhs.value[i];
    return *this;
}

जब संकलक ऊपर परिभाषित फ़ंक्शन टेम्पलेट को तुरंत चालू करता है, तो निम्न कोड उत्पन्न हो सकता है:[citation needed]

template <>
Vector<2>& Vector<2>::operator+=(const Vector<2>& rhs) 
{
    value[0] += rhs.value[0];
    value[1] += rhs.value[1];
    return *this;
}

कंपाइलर को कसरत ज्यादा समय तक करने में सक्षम होना चाहिए क्योंकि नमूना पैरामीटर की लंबाई संकलन समय पर स्थिर है।

जबकि सावधानी बरतें क्योंकि इससे सांकेतिक चिन्ह दब सकता है क्योंकि प्रत्येक एन सदिश के लिए अलग-अलग अनियंत्रित सांकेतिक चिन्ह उत्पन्न होगा।

स्थैतिक बहुरूपता

प्रकार बहुरूपता एक सामान्य मानक प्रोग्रामिंग सुविधा है जहां व्युत्पन्न वस्तुओं को उनके मूल वस्तु के उदाहरणों के रूप में उपयोग किया जा सकता है लेकिन जहां व्युत्पन्न वस्तुओं के तरीकों को लागू किया जाएगा, जैसा कि इस कोड में है

class Base
{
public:
    virtual void method() { std::cout << "Base"; }
    virtual ~Base() {}
};

class Derived : public Base
{
public:
    virtual void method() { std::cout << "Derived"; }
};

int main()
{
    Base *pBase = new Derived;
    pBase->method(); //outputs "Derived"
    delete pBase;
    return 0;
}

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

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

template <class Derived>
struct base
{
    void interface()
    {
         // ...
         static_cast<Derived*>(this)->implementation();
         // ...
    }
};

struct derived : base<derived>
{
     void implementation()
     {
         // ...
     }
};

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

स्टेटिक टेबल जनरेशन

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

#include <iostream>
#include <array>

constexpr int TABLE_SIZE = 10;

/**
 * Variadic template for a recursive helper struct.
 */
template<int INDEX = 0, int ...D>
struct Helper : Helper<INDEX + 1, D..., INDEX * INDEX> { };

/**
 * Specialization of the template to end the recursion when the table size reaches TABLE_SIZE.
 */
template<int ...D>
struct Helper<TABLE_SIZE, D...> {
  static constexpr std::array<int, TABLE_SIZE> table = { D... };
};

constexpr std::array<int, TABLE_SIZE> table = Helper<>::table;

enum  {
  FOUR = table[2] // compile time use
};

int main() {
  for (int i=0; i < TABLE_SIZE; i++) {
    std::cout << table[i]  << std::endl; // run time use
  }
  std::cout << "FOUR: " << FOUR << std::endl;
}

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

template <int INDEX = 0, int ...D> struct Helper : Helper<INDEX + 1, D..., INDEX * INDEX> {
};
template<> struct Helper<0, <>> : Helper<0 + 1, 0 * 0> {
};
template<> struct Helper<1, <0>> : Helper<1 + 1, 0, 1 * 1> {
};
template<> struct Helper<2, <0, 1>> : Helper<2 + 1, 0, 1, 2 * 2> {
};
template<> struct Helper<3, <0, 1, 4>> : Helper<3 + 1, 0, 1, 4, 3 * 3> {
};
template<> struct Helper<4, <0, 1, 4, 9>> : Helper<4 + 1, 0, 1, 4, 9, 4 * 4> {
};
template<> struct Helper<5, <0, 1, 4, 9, 16>> : Helper<5 + 1, 0, 1, 4, 9, 16, 5 * 5> {
};
template<> struct Helper<6, <0, 1, 4, 9, 16, 25>> : Helper<6 + 1, 0, 1, 4, 9, 16, 25, 6 * 6> {
};
template<> struct Helper<7, <0, 1, 4, 9, 16, 25, 36>> : Helper<7 + 1, 0, 1, 4, 9, 16, 25, 36, 7 * 7> {
};
template<> struct Helper<8, <0, 1, 4, 9, 16, 25, 36, 49>> : Helper<8 + 1, 0, 1, 4, 9, 16, 25, 36, 49, 8 * 8> {
};
template<> struct Helper<9, <0, 1, 4, 9, 16, 25, 36, 49, 64>> : Helper<9 + 1, 0, 1, 4, 9, 16, 25, 36, 49, 64, 9 * 9> {
};
template<> struct Helper<10, <0, 1, 4, 9, 16, 25, 36, 49, 64, 81>> {
  static constexpr std::array<int, TABLE_SIZE> table = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81};
};

चूंकि सी ++ 17 इसे और अधिक आसानी से लिखा जा सकता है:

 
#include <iostream>
#include <array>

constexpr int TABLE_SIZE = 10;

constexpr std::array<int, TABLE_SIZE> table = [] { // OR: constexpr auto table
  std::array<int, TABLE_SIZE> A = {};
  for (unsigned i = 0; i < TABLE_SIZE; i++) {
    A[i] = i * i;
  }
  return A;
}();

enum  {
  FOUR = table[2] // compile time use
};

int main() {
  for (int i=0; i < TABLE_SIZE; i++) {
    std::cout << table[i]  << std::endl; // run time use
  }
  std::cout << "FOUR: " << FOUR << std::endl;
}

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

                                                                
#include <iostream>
#include <array>

constexpr int TABLE_SIZE = 20;
constexpr int OFFSET = 12;

/**
 * Template to calculate a single table entry
 */
template <typename VALUETYPE, VALUETYPE OFFSET, VALUETYPE INDEX>
struct ValueHelper {
  static constexpr VALUETYPE value = OFFSET + INDEX * INDEX;
};

/**
 * Variadic template for a recursive helper struct.
 */
template<typename VALUETYPE, VALUETYPE OFFSET, int N = 0, VALUETYPE ...D>
struct Helper : Helper<VALUETYPE, OFFSET, N+1, D..., ValueHelper<VALUETYPE, OFFSET, N>::value> { };

/**
 * Specialization of the template to end the recursion when the table size reaches TABLE_SIZE.
 */
template<typename VALUETYPE, VALUETYPE OFFSET, VALUETYPE ...D>
struct Helper<VALUETYPE, OFFSET, TABLE_SIZE, D...> {
  static constexpr std::array<VALUETYPE, TABLE_SIZE> table = { D... };
};

constexpr std::array<uint16_t, TABLE_SIZE> table = Helper<uint16_t, OFFSET>::table;

int main() {
  for (int i = 0; i < TABLE_SIZE; i++) {
    std::cout << table[i] << std::endl;
  }
}

जिसे C++17 का उपयोग करके इस प्रकार लिखा जा सकता है:

#include <iostream>
#include <array>

constexpr int TABLE_SIZE = 20;
constexpr int OFFSET = 12;

template<typename VALUETYPE, VALUETYPE OFFSET>
constexpr std::array<VALUETYPE, TABLE_SIZE> table = [] { // OR: constexpr auto table
  std::array<VALUETYPE, TABLE_SIZE> A = {};
  for (unsigned i = 0; i < TABLE_SIZE; i++) {
    A[i] = OFFSET + i * i;
  }
  return A;
}();

int main() {
  for (int i = 0; i < TABLE_SIZE; i++) {
    std::cout << table<uint16_t, OFFSET>[i] << std::endl;
  }
}


अवधारणाएं

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

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

#include <boost/type_index.hpp> // for pretty printing of types
#include <iostream>
#include <tuple>

/**
 * Type representation of words to print
 */
struct Fizz {};
struct Buzz {};
struct FizzBuzz {};
template<size_t _N> struct number { constexpr static size_t N = _N; };

/**
 * Concepts used to define condition for specializations
 */
template<typename Any> concept has_N = requires{ requires Any::N - Any::N == 0; };
template<typename A> concept fizz_c = has_N<A> && requires{ requires A::N % 3 == 0; };
template<typename A> concept buzz_c = has_N<A> && requires{ requires A::N % 5 == 0;};
template<typename A> concept fizzbuzz_c = fizz_c<A> && buzz_c<A>;

/**
 * By specializing `res` structure, with concepts requirements, proper instantiation is performed
 */
template<typename X> struct res;
template<fizzbuzz_c X> struct res<X> { using result = FizzBuzz; };
template<fizz_c X> struct res<X> { using result = Fizz; };
template<buzz_c X> struct res<X> { using result = Buzz; };
template<has_N X> struct res<X> { using result = X; };

/**
 * Predeclaration of concatenator
 */
template <size_t cnt, typename... Args> 
struct concatenator;

/**
 * Recursive way of concatenating next types
 */
template <size_t cnt, typename ... Args>
struct concatenator<cnt, std::tuple<Args...>> 
{ using type = typename concatenator<cnt - 1, std::tuple< typename res< number<cnt> >::result, Args... >>::type;};

/**
 * Base case
 */
template <typename... Args> struct concatenator<0, std::tuple<Args...>> { using type = std::tuple<Args...>;};

/**
 * Final result getter
 */
template<size_t Amount>
using fizz_buzz_full_template = typename concatenator<Amount - 1, std::tuple<typename res<number<Amount>>::result>>::type;

int main()
{
	// printing result with boost, so it's clear
	std::cout << boost::typeindex::type_id<fizz_buzz_full_template<100>>().pretty_name() << std::endl;
/*
Result:
	std::tuple<number<1ul>, number<2ul>, Fizz, number<4ul>, Buzz, Fizz, number<7ul>, number<8ul>, Fizz, Buzz, number<11ul>, Fizz, number<13ul>, number<14ul>, FizzBuzz, number<16ul>, number<17ul>, Fizz, number<19ul>, Buzz, Fizz, number<22ul>, number<23ul>, Fizz, Buzz, number<26ul>, Fizz, number<28ul>, number<29ul>, FizzBuzz, number<31ul>, number<32ul>, Fizz, number<34ul>, Buzz, Fizz, number<37ul>, number<38ul>, Fizz, Buzz, number<41ul>, Fizz, number<43ul>, number<44ul>, FizzBuzz, number<46ul>, number<47ul>, Fizz, number<49ul>, Buzz, Fizz, number<52ul>, number<53ul>, Fizz, Buzz, number<56ul>, Fizz, number<58ul>, number<59ul>, FizzBuzz, number<61ul>, number<62ul>, Fizz, number<64ul>, Buzz, Fizz, number<67ul>, number<68ul>, Fizz, Buzz, number<71ul>, Fizz, number<73ul>, number<74ul>, FizzBuzz, number<76ul>, number<77ul>, Fizz, number<79ul>, Buzz, Fizz, number<82ul>, number<83ul>, Fizz, Buzz, number<86ul>, Fizz, number<88ul>, number<89ul>, FizzBuzz, number<91ul>, number<92ul>, Fizz, number<94ul>, Buzz, Fizz, number<97ul>, number<98ul>, Fizz, Buzz>
*/
}


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

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

यह भी देखें

संदर्भ

  1. Scott Meyers (12 May 2005). Effective C++: 55 Specific Ways to Improve Your Programs and Designs. Pearson Education. ISBN 978-0-13-270206-5.
  2. See History of TMP on Wikibooks
  3. Veldhuizen, Todd L. (2003). "C++ टेम्प्लेट ट्यूरिंग पूर्ण हैं". CiteSeerX 10.1.1.14.3670. {{cite journal}}: Cite journal requires |journal= (help)
  4. "Iterator Facade - 1.79.0".
  5. "Constraints and concepts (since C++20) - cppreference.com". en.cppreference.com.
  6. Czarnecki, K.; O'Donnell, J.; Striegnitz, J.; Taha, Walid Mohamed (2004). "DSL implementation in metaocaml, template haskell, and C++" (PDF). University of Waterloo, University of Glasgow, Research Centre Julich, Rice University. C++ Template Metaprogramming suffers from a number of limitations, including portability problems due to compiler limitations (although this has significantly improved in the last few years), lack of debugging support or IO during template instantiation, long compilation times, long and incomprehensible errors, poor readability of the code, and poor error reporting. {{cite journal}}: Cite journal requires |journal= (help)
  7. Sheard, Tim; Jones, Simon Peyton (2002). "Template Meta-programming for Haskell" (PDF). ACM 1-58113-415-0/01/0009. Robinson's provocative paper identifies C++ templates as a major, albeit accidental, success of the C++ language design. Despite the extremely baroque nature of template meta-programming, templates are used in fascinating ways that extend beyond the wildest dreams of the language designers. Perhaps surprisingly, in view of the fact that templates are functional programs, functional programmers have been slow to capitalize on C++'s success {{cite journal}}: Cite journal requires |journal= (help)


बाहरी संबंध