2009-08-03 19 views
30

मैं एक समस्या है .. मैं खाका Metaprogramming समझ में नहींखाका Metaprogramming - मैं अभी भी यह नहीं मिलता है :(

समस्या है: मैं एक बहुत पढ़ा लेकिन यह करने के लिए ज्यादा मतलब नहीं है।। मुझे:/

तथ्य nr.1: टेम्पलेट Metaprogramming तेजी

template <int N> 
struct Factorial 
{ 
    enum { value = N * Factorial<N - 1>::value }; 
}; 

template <> 
struct Factorial<0> 
{ 
    enum { value = 1 }; 
}; 

// Factorial<4>::value == 24 
// Factorial<0>::value == 1 
void foo() 
{ 
    int x = Factorial<4>::value; // == 24 
    int y = Factorial<0>::value; // == 1 
} 

तो यह Metaprogram तेजी से ... लगातार शाब्दिक के beacause है
लेकिन: जहां में असली दुनिया हम लगातार Literals क्या ज़रूरत है?
अधिकांश प्रोग्राम जो मैं उपयोगकर्ता इनपुट पर प्रतिक्रिया का उपयोग करता हूं।

तथ्य एन.आर.। 2: टेम्पलेट मेटाप्रोग्रामिंग बेहतर रखरखाव को लागू कर सकता है।

हाँ। फैक्टोरियल उदाहरण रखरखाव योग्य हो सकता है ... लेकिन जब जटिल कार्यों की बात आती है, तो मैं और अन्य सी ++ प्रोग्रामर कार्यों को पढ़ नहीं सकते हैं। और डिबगिंग विकल्प खराब हैं। (या कम से कम मुझे नहीं पता कि कैसे डिबग करना है)

टेम्पलेट मेटाप्रोग्रामिंग कहां समझता है?

+3

यह मुझे कभी ज्यादा समझ में नहीं आया ... – Kawa

+10

बुरा मत समझो, शायद ही कोई इसे प्राप्त करता है। –

उत्तर

26
बस भाज्य के रूप में

गैर कार्यात्मक भाषाओं में प्रत्यावर्तन के एक यथार्थवादी उदाहरण नहीं है, न तो यह टेम्पलेट metaprogramming के एक यथार्थवादी उदाहरण है। यह केवल मानक उदाहरण है जब लोग आपको रिकर्सन दिखाना चाहते हैं।

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

यहाँ बढ़ावा प्रलेखन पृष्ठों से वास्तव में एक अच्छा ट्यूटोरियल (वास्तव में एक brilliant book से कुछ अंश, अच्छी तरह से लायक पढ़ने) है।

http://www.boost.org/doc/libs/1_39_0/libs/mpl/doc/tutorial/representing-dimensions.html

+3

अच्छा उत्तर। +1 - मेरी इच्छा है कि लोग एक बेहतर मानक उदाहरण पर सहमत हो गए हों। आम तौर पर, मानों की गणना करने के लिए मेटाप्रोग्रामिंग का उपयोग करना व्यर्थ है। यह सीखने के अभ्यास के रूप में प्रबुद्ध है, टीएमपी को समझने की कोशिश करते समय, लेकिन उपयोग के मामले के रूप में नहीं, बल्कि लोगों को यह समझाने के लिए एक विक्रय बिंदु के रूप में नहीं है कि यह सुविधा कितनी शानदार है। – jalf

+1

मैं मूल्य पीढ़ी को पूरी तरह से लिख नहीं पाऊंगा :) http://stackoverflow.com/questions/699781/c-binary-constant-literal –

+0

बेशक यह उपयोगी हो सकता है, लेकिन वास्तव में लोगों को मनाने के लिए यह बड़ी बिक्री बिंदु नहीं है यह सुविधा सार्थक है। द्विआधारी उदाहरण सामान्य से बेहतर है, लेकिन फिर भी, स्पष्ट सवाल यह है कि "इसे रनटाइम पर क्यों न करें? ऐसा नहीं है कि यह निषिद्ध रूप से महंगा है।" क्या यह वास्तव में सी ++ के शीर्ष पर एक और ट्यूरिंग-पूर्ण भाषा को ले जाने के लिए औचित्य है? ;) – jalf

2

मेरा सुझाव है कि आप आंद्रेई अलेक्जेंड्रेस्कू द्वारा Modern C++ Design पढ़ लें - यह शायद सी ++ टेम्पलेट मेटाप्रोग्रामिंग के असली दुनिया के उपयोगों पर सबसे अच्छी किताबों में से एक है; और कई समस्याओं का वर्णन करता है जो सी ++ टेम्पलेट्स एक उत्कृष्ट समाधान हैं।

+14

प्रत्येक सी ++ डेवलपर को उस पुस्तक को पढ़ना चाहिए, लेकिन सवाल का जवाब देने में यह सब उपयोगी नहीं है, इसी कारण से Google को केवल एक लिंक प्रदान करना आम तौर पर फहराया जाता है। इसलिए उत्तर खोजने के लिए एक जगह माना जाना चाहिए, अन्य संसाधनों के लिंक नहीं, जहां आप इसके बजाय खोज करने का प्रयास कर सकते हैं। – jalf

+0

स्कॉट मेयर्स के प्रभावी सी ++ के तीसरे संस्करण में एक उदाहरण भी शामिल है जो काफी अच्छी तरह से समझाया गया है। (हालांकि यह मेटा फ़ंक्शंस के बजाय फ़ंक्शन ओवरलोडिंग के बारे में है और इस प्रकार पहले "वास्तविक टीएमपी" के रूप में प्रतीत नहीं होता है।) – sbi

2

TMP अस्थायी हटाने के द्वारा मैट्रिक्स आपरेशन के अनुकूलन के लिए आयामी शुद्धता सुनिश्चित करने की तरह कुछ से इस्तेमाल किया जा सकता है (जो बड़े पैमाने पर यह सुनिश्चित करना समय से विभाजित नहीं किया जा सकता है, लेकिन दूरी एक वेग चर करने के लिए समय से विभाजित और सौंपा जा सकता है) वस्तुओं और विलय loops जब कई matrices शामिल हैं।

+0

द्रव्यमान समय के साथ विभाजित किया जा सकता है। नतीजा सिर्फ "द्रव्यमान प्रति समय" प्रकार होना चाहिए;) लेकिन हाँ, टीएमपी का उपयोग इसे लागू करने के लिए किया जा सकता है। – jalf

+0

कुछ भी किसी भी चीज़ से विभाजित/गुणा किया जा सकता है, यह अतिरिक्त/घटाव है जो लोगों को यात्रा करता है। –

3

स्कॉट Meyers TMP का उपयोग कर कोड की कमी लागू करने पर काम कर रहा है।

इसका काफी अच्छा पढ़ा:
http://www.artima.com/cppsource/codefeatures.html

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

+0

दरअसल उसका नाम "मेयर्स" है। (नाइटपिकिंग के लिए खेद है।) – sbi

+0

सही। :-) –

9

तो यह मेटाप्रोग्राम तेज़ है ... कॉन्स्टेंट लिटलल का बीकॉज़। लेकिन: असली दुनिया में जहां हमारे पास लगातार साहित्य हैं? अधिकांश प्रोग्राम जो मैं उपयोगकर्ता इनपुट पर प्रतिक्रिया का उपयोग करता हूं।

यही कारण है कि यह शायद ही कभी मूल्यों के लिए उपयोग किया जाता है। आमतौर पर, यह प्रकारों पर प्रयोग किया जाता है। नए प्रकारों की गणना और उत्पन्न करने के लिए प्रकारों का उपयोग करना।

कई वास्तविक दुनिया के उपयोग हैं, जिनमें से कुछ आप पहले ही परिचित हैं, भले ही आपको इसका एहसास न हो।

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

पॉइंटर्स को पैच करने के लिए ताकि उन्हें इटरेटर के रूप में उपयोग किया जा सके। एक पुनरावर्तक को value_type जैसे कुछ प्रकार के टाइपपीफ का पर्दाफाश करना चाहिए। पॉइंटर्स ऐसा नहीं करते हैं।

जैसे कि निम्न (मूल रूप से आप Boost.Iterator में क्या लगता है के समान)

template <typename T> 
struct value_type { 
    typedef typename T::value_type type; 
}; 

template <typename T> 
struct value_type<T*> { 
    typedef T type; 
}; 

एक बहुत ही सरल टेम्पलेट metaprogram है, लेकिन जो के रूप में

तो कोड बहुत उपयोगी है। यह आपको किसी भी इटरेटर प्रकार टी के मान प्रकार को प्राप्त करने देता है, चाहे वह एक सूचक या वर्ग हो, बस value_type<T>::type द्वारा।

और मुझे लगता है कि उपरोक्तता के आने पर ऊपर दिए गए कुछ स्पष्ट लाभ हैं। आपके एल्गोरिदम केवल इटरेटर्स पर काम कर रहे हैं केवल एक बार लागू किया जाना है। इस चाल के बिना, आपको पॉइंटर्स के लिए एक कार्यान्वयन करना होगा, और दूसरा "उचित" वर्ग-आधारित इटरेटर्स के लिए।

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

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

लेकिन अधिकांश समय, टेम्पलेट मेटाप्रोग्रामिंग का उपयोग छोटे, अलग मामलों में किया जाता है, मूल रूप से बाधाओं और असाधारण मामलों को सुचारु बनाने के लिए, प्रकारों का एक सेट बनाने और समान व्यवहार करने के लिए, जो आपको सामान्य प्रोग्रामिंग का उपयोग करने की अनुमति देता है अधिक कुशलता से

8

अलेक्जेंड्रेस्कू के आधुनिक सी ++ डिजाइन के लिए अनुशंसा को सेकेंड करना।

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

ऐसा करने के लिए 60 अलग-अलग वर्गों को कार्यान्वित करने में बहुत परेशान, हार्ड-टू-कोड कोड डुप्लिकेशन शामिल होगा। टेम्पलेट मेटाप्रोग्रामिंग का मतलब है कि हम कोड 0 इकाई के रूप में प्रत्येक अवधारणा को कार्यान्वित कर सकते हैं, और प्रोग्रामर को संकलन-समय पर इन अवधारणाओं के संयोजन को तत्काल करने के लिए एक सरल इंटरफ़ेस प्रदान कर सकते हैं।

आयामी विश्लेषण भी एक उत्कृष्ट उदाहरण है, लेकिन अन्य लोगों ने इसे कवर किया है।

मैंने कभी-कभी लोगों के सिर के साथ गड़बड़ करने के लिए कुछ सरल संकलन-समय छद्म-यादृच्छिक संख्या जेनरेटर भी लिखे थे, लेकिन यह वास्तव में आईएमओ की गणना नहीं करता है।

+5

लोगों के सिर के साथ मेसिंग बेहतरीन उपयोगों में से एक है जिसके लिए प्रोग्रामिंग लगाया जा सकता है! उस के मूल्य को कम मत समझो। : p – jalf

15

मैं संकलन समय के दौरान शफल को अनुकूलित करने के लिए एसएसई स्विजलिंग ऑपरेटरों के लिए टेम्पलेट मेटा-प्रोग्रामिंग का उपयोग करता हूं।

SSE swizzles ('शफ़ल') केवल एक बाइट शाब्दिक (तत्काल मूल्य) के रूप में नीचे दब जाती है, इसलिए हम एक 'मुखौटा विलय' टेम्पलेट वर्ग है कि जब कई फेरबदल होते हैं के लिए संकलन समय के दौरान मास्क विलीन हो जाती है बनाया:

template <unsigned target, unsigned mask> 
struct _mask_merger 
{ 
    enum 
    { 
     ROW0 = ((target >> (((mask >> 0) & 3) << 1)) & 3) << 0, 
     ROW1 = ((target >> (((mask >> 2) & 3) << 1)) & 3) << 2, 
     ROW2 = ((target >> (((mask >> 4) & 3) << 1)) & 3) << 4, 
     ROW3 = ((target >> (((mask >> 6) & 3) << 1)) & 3) << 6, 

     MASK = ROW0 | ROW1 | ROW2 | ROW3, 
    }; 
}; 

यह काम करता है और उत्पन्न कोड ओवरहेड और थोड़ा अतिरिक्त संकलन समय के बिना उल्लेखनीय कोड बनाता है।

3

यहाँ एक तुच्छ उदाहरण एक द्विआधारी निरंतर कनवर्टर एक पिछले प्रश्न से यहाँ StackOverflow पर है,,:

C++ binary constant/literal

template< unsigned long long N > 
struct binary 
{ 
    enum { value = (N % 10) + 2 * binary<N/10> :: value } ; 
}; 
template<> 
struct binary<0> 
{ 
    enum { value = 0 } ; 
}; 
5

, भाज्य उदाहरण के बारे में के लिए के रूप में "नमस्ते वास्तविक दुनिया TMP रूप में उपयोगी है विश्व!" सामान्य प्रोग्रामिंग के लिए है: यह आपको कुछ उपयोगी तकनीकों (पुनरावृत्ति के बजाय रिकर्सन, "अन्य-अगर-फिर" इत्यादि) को एक बहुत ही सरल, अपेक्षाकृत आसान समझने के लिए है, जिसमें आपके प्रत्येक के लिए बहुत प्रासंगिकता नहीं है -डे कोडिंग। (जब पिछली बार जब आप एक प्रोग्राम है जो उत्सर्जित "Hello, world" लिखने के लिए आवश्यक था?)

TMP संकलन समय पर एल्गोरिदम को क्रियान्वित करने के बारे में है और यह कुछ स्पष्ट फायदे का अर्थ है:

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

, वहाँ नुकसान है, भी:

  • त्रुटि संदेश भयानक हो सकता है।
  • कोई डिबगिंग नहीं है।
  • कोड अक्सर पढ़ने के लिए मुश्किल है।

हमेशा के रूप में, आपको केवल हर मामले में नुकसान के खिलाफ लाभों का भार उठाना होगा।

एक अधिक उपयोगी उदाहरण के लिए के रूप में: एक बार जब आप प्रकार सूची और बुनियादी संकलन समय उन पर काम कर रही एल्गोरिदम समझा है, तो आप समझ सकते हैं निम्नलिखित:

typedef 
    type_list_generator< signed char 
         , signed short 
         , signed int 
         , signed long 
         >::result_type 
    signed_int_type_list; 

typedef 
    type_list_find_if< signed_int_type_list 
        , exact_size_predicate<8> 
        >::result_type 
    int8_t; 

typedef 
    type_list_find_if< signed_int_type_list 
        , exact_size_predicate<16> 
        >::result_type 
    int16_t; 

typedef 
    type_list_find_if< signed_int_type_list 
        , exact_size_predicate<32> 
        >::result_type 
    int32_t; 

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

एक और उदाहरण यह है:

template< typename TFunc, typename TFwdIter > 
typename func_traits<TFunc>::result_t callFunc(TFunc f, TFwdIter begin, TFwdIter end); 

एक समारोह f और तार का एक अनुक्रम, इस समारोह के हस्ताक्षर काटना सही प्रकार में अनुक्रम से तार कनवर्ट करते हैं, और इन के साथ समारोह कॉल करेंगे को देखते हुए वस्तुओं। और यह ज्यादातर टीएमपी अंदर है।

3

टीएमपी का अर्थ तेजी से या अधिक रखरखाव कोड नहीं है। मैंने spirit लाइब्रेरी को एक सरल एसक्यूएल अभिव्यक्ति पार्सर को कार्यान्वित करने के लिए बढ़ावा दिया जो एक मूल्यांकन वृक्ष संरचना बनाता है। जबकि विकास का समय कम हो गया था क्योंकि मुझे टीएमपी और लैम्बडा के साथ कुछ परिचितता थी, सीखने की अवस्था "कक्षाओं के साथ सी" डेवलपर्स के लिए एक ईंट की दीवार है, और प्रदर्शन पारंपरिक LEX/YACC के रूप में उतना अच्छा नहीं है।

मैं टेम्पलेट मेटा प्रोग्रामिंग को अपने टूल-बेल्ट में बस एक और टूल के रूप में देखता हूं। जब यह आपके लिए काम करता है तो इसका उपयोग करें, अगर ऐसा नहीं होता है, तो दूसरे उपकरण का उपयोग करें।

2

'स्थिर कॉन्स' मान भी काम करते हैं। और पॉइंटर्स-टू-सदस्य। और संकलन-समय के तर्क के रूप में प्रकारों (स्पष्ट और कटौती) की दुनिया को मत भूलना!

लेकिन: असली दुनिया में कहां हमारे पास निरंतर साहित्य हैं?

मान लें कि आपके पास कुछ कोड है जो जितनी जल्दी हो सके चलाना है। इसमें वास्तव में आपके सीपीयू-बाध्य गणना का महत्वपूर्ण आंतरिक पाश शामिल है। आप इसे तेजी से बनाने के लिए अपने निष्पादन योग्य आकार को बढ़ाने के इच्छुक होंगे। ऐसा लगता है:

double innerLoop(const bool b, const vector<double> & v) 
{ 
    // some logic involving b 

    for (vector::const_iterator it = v.begin; it != v.end(); ++it) 
    { 
     // significant logic involving b 
    } 

    // more logic involving b 
    return .... 
} 

विवरण महत्वपूर्ण नहीं हैं, लेकिन 'बी' का उपयोग कार्यान्वयन में व्यापक है।

अब, टेम्पलेट्स के साथ, आप इसे थोड़ा refactor कर सकते हैं:

template <bool b> double innerLoop_B(vector<double> v) { ... same as before ... } 
double innerLoop(const bool b, const vector<double> & v) 
{ return b ? innerLoop_templ_B<true>(v) : innerLoop_templ_B<false>(v)); } 

किसी भी समय आप उनके लिए एक अपेक्षाकृत छोटे, असतत, एक पैरामीटर के मानों का सेट आप कर सकते हैं स्वचालित रूप से इन्स्तांत अलग संस्करण है।

'बी' CPU पहचान पर आधारित होने पर संभावनाओं पर विचार करें। आप रन-टाइम पहचान के आधार पर कोड का एक अलग-अनुकूलित सेट चला सकते हैं। सभी एक ही स्रोत कोड से, या आप मूल्यों के कुछ सेट के लिए कुछ फ़ंक्शंस का विशेषज्ञ कर सकते हैं।

एक ठोस उदाहरण के रूप में, मैंने एक बार कुछ कोड देखा जो कुछ पूर्णांक निर्देशांक को मर्ज करने के लिए आवश्यक था। समन्वय प्रणाली 'ए' दो संकल्पों में से एक था (संकलन समय पर जाना जाता है), और समन्वय प्रणाली 'बी' दो अलग-अलग संकल्पों में से एक था (संकलन समय पर भी जाना जाता है)। लक्ष्य समन्वय प्रणाली को दो स्रोत समन्वय प्रणालियों के कम से कम आम बहुसंख्यक होने की आवश्यकता होती है। एक पुस्तकालय का उपयोग संकलन समय पर एलसीएम की गणना करने और विभिन्न संभावनाओं के लिए कोड को तत्काल करने के लिए किया गया था।

संबंधित मुद्दे