c++ - टेम्पलेट कटौती में आंशिक क्रम प्रक्रिया क्या है



templates c++11 (1)

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

सबसे पहले, आपके द्वारा उद्धृत अनुच्छेद की पहली वाक्य कहती है:

शामिल प्रत्येक टेम्पलेट्स के लिए मूल फ़ंक्शन प्रकार और रूपांतरित फ़ंक्शन प्रकार है । [...]

पकड़ो, यह " रूपांतरित कार्य प्रकार " क्या है? अनुच्छेद 14.5.6.2/3 बताता है कि:

प्रत्येक प्रकार, गैर-प्रकार, या टेम्पलेट टेम्पलेट पैरामीटर (टेम्पलेट पैरामीटर पैक (14.5.3) सहित क्रमशः परिवर्तित टेम्पलेट का उत्पादन करने के लिए क्रमशः एक अद्वितीय प्रकार, मान या वर्ग टेम्पलेट संश्लेषित करें और उस पैरामीटर की प्रत्येक घटना के लिए इसे प्रतिस्थापित करें टेम्पलेट के समारोह प्रकार में [...]

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

template<typename T, typename U>
void foo(T, U) // #1

अब चूंकि T और U टाइप पैरामीटर हैं, उपर्युक्त पैराग्राफ हमें T (जो भी) के लिए एक समान प्रकार का तर्क लेने के लिए कह रहा है और इसे फ़ंक्शन हस्ताक्षर में हर जगह प्रतिस्थापित करता है जहां T दिखाई देता है, फिर U लिए ऐसा ही करना है।

अब " एक अद्वितीय प्रकार को संश्लेषित करना " का अर्थ है कि आपको एक फर्जी प्रकार चुनना है जिसे आपने कहीं और नहीं उपयोग किया है, और हम उस P1 को कॉल कर सकते हैं (और फिर U लिए P2 चुनें), लेकिन इससे हमारी चर्चा बेकार औपचारिक हो जाएगी।

आइए केवल चीजों को सरल bool और U लिए T और bool लिए int चुनें - हम उन प्रकारों का कहीं और उपयोग नहीं कर रहे हैं, इसलिए हमारे उद्देश्यों के लिए, वे P1 और P1 ही अच्छे हैं।

तो परिवर्तन के बाद, हमारे पास है:

void foo(int, bool) // #1b

यह हमारे मूल foo() फ़ंक्शन टेम्पलेट के लिए रूपांतरित फ़ंक्शन प्रकार है।

तो चलिए आपके द्वारा उद्धृत अनुच्छेद की व्याख्या करना जारी रखें। दूसरी वाक्य कहती है:

कटौती प्रक्रिया ट्रांसफॉर्म किए गए प्रकार को तर्क टेम्पलेट और अन्य टेम्पलेट के मूल प्रकार पैरामीटर टेम्पलेट के रूप में उपयोग करती है। [...]

रुको, क्या " अन्य टेम्पलेट "? हमारे पास अभी तक foo() का एक अधिभार है। ठीक है, लेकिन फ़ंक्शन टेम्पलेट्स के बीच ऑर्डर करने के उद्देश्य के लिए, हमें उनमें से कम से कम दो की आवश्यकता है, इसलिए हम बेहतर एक दूसरा निर्माण करेंगे। आइए उपयोग करें:

template<typename T>
void foo(T const*, X<T>) // #2

जहां X हमारे कुछ वर्ग टेम्पलेट है।

अब इस दूसरे समारोह टेम्पलेट के साथ क्या? आह, हां, हमें वही करने की ज़रूरत है जो हमने पहले foo() के पहले अधिभार के लिए किया था और इसे बदल दिया: तो फिर, चलिए T लिए कुछ प्रकार का तर्क चुनते हैं और हर जगह T प्रतिस्थापित करते हैं। मैं इस बार char (हम इस उदाहरण में कहीं और इसका उपयोग नहीं कर रहे हैं, इसलिए यह कुछ कल्पित P3 के रूप में अच्छा है):

void foo(char const*, X<char>) #2b

बढ़िया, अब उसके पास दो फ़ंक्शन टेम्पलेट्स और संबंधित रूपांतरित फ़ंक्शन प्रकार हैं। तो यह निर्धारित करने के लिए कि #1 #2 से अधिक विशिष्ट है या इसके विपरीत?

उपर्युक्त वाक्य से हम क्या जानते हैं कि मूल टेम्पलेट्स और उनके रूपांतरित फ़ंक्शन प्रकारों को किसी भी तरह मिलान किया जाना चाहिए। पर कैसे? यही तीसरी वाक्य बताती है:

आंशिक क्रम तुलना में शामिल प्रत्येक प्रकार के लिए यह प्रक्रिया दो बार की जाती है: एक बार ट्रांसफॉर्म किए गए टेम्पलेट -1 को तर्क टेम्पलेट और टेम्पलेट -2 के रूप में पैरामीटर टेम्पलेट के रूप में उपयोग करके और फिर टेम्पलेट टेम्पलेट और टेम्पलेट -1 के रूप में परिवर्तित टेम्पलेट -2 का उपयोग करके पैरामीटर टेम्पलेट के रूप में

तो मूल रूप से पहले टेम्पलेट ( #1b ) के रूपांतरित रूपांतरित फ़ंक्शन प्रकार को मूल दूसरे टेम्पलेट ( #2 ) के फ़ंक्शन प्रकार के विरुद्ध मेल किया जाना है। और निश्चित रूप से दूसरे तरीके से, दूसरे दूसरे टेम्पलेट ( #2b ) के रूपांतरित फ़ंक्शन प्रकार को मूल पहले टेम्पलेट ( #1 ) के फ़ंक्शन प्रकार के विरुद्ध मिलान किया जाना है।

यदि मिलान एक दिशा में सफल होगा लेकिन दूसरे में नहीं, तो हम जान लेंगे कि टेम्पलेट्स में से एक दूसरे की तुलना में अधिक विशिष्ट है। अन्यथा, न तो अधिक विशिष्ट है।

चलो शुरू करो। सबसे पहले, हमें मिलना होगा:

void foo(int, bool) // #1b

विरुद्ध:

template<typename T>
void foo(T const*, X<T>) // #2

क्या कोई तरीका है कि हम T पर कटौती कर सकते हैं ताकि T const* बिल्कुल int हो जाए और X<T> बिल्कुल bool हो जाए? (वास्तव में, एक सटीक मिलान आवश्यक नहीं है, लेकिन इस नियम के लिए वास्तव में कुछ अपवाद हैं और वे आंशिक क्रमिक तंत्र को चित्रित करने के उद्देश्य से प्रासंगिक नहीं हैं, इसलिए हम उन्हें अनदेखा करेंगे)।

मुश्किल से। तो आइए दूसरी तरफ से मिलान करने का प्रयास करें। हमें मिलना चाहिए:

void foo(char const*, X<char>) // #2b

विरुद्ध:

template<typename T, typename U>
void foo(T, U) // #1

क्या हम T और U को क्रमशः char const* और X<char> लिए सटीक मिलान बनाने के लिए char const* हैं? ज़रूर! यह तुच्छ है। हम बस T = char const* और U = X<char> चुनते हैं।

तो हमने पाया कि foo() ( #1b ) के हमारे पहले अधिभार के रूपांतरित फ़ंक्शन प्रकार को foo() ( #2 ) के हमारे दूसरे अधिभार के मूल फ़ंक्शन टेम्पलेट के विरुद्ध मेल नहीं किया जा सकता है; दूसरी ओर, दूसरे अधिभार ( #2b ) के रूपांतरित फ़ंक्शन प्रकार को पहले ओवरलोड ( #1 ) के मूल फ़ंक्शन टेम्पलेट के विरुद्ध मिलान किया जा सकता है।

निष्कर्ष? foo() का दूसरा अधिभार पहले की तुलना में अधिक विशिष्ट है।

प्रति-उदाहरण चुनने के लिए, इन दो फ़ंक्शन टेम्पलेट्स पर विचार करें:

template<typename T, typename U>
void bar(X<T>, U)

template<typename T, typename U>
void bar(U, T const*)

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

निष्कर्ष? न तो फ़ंक्शन टेम्पलेट दूसरे की तुलना में अधिक विशिष्ट है।

अब इस स्पष्टीकरण में मैंने कई विवरण, नियमों के अपवाद, और मानक में गुप्त मार्गों को अनदेखा कर दिया है, लेकिन आपके द्वारा उद्धृत अनुच्छेद में उल्लिखित तंत्र वास्तव में यह है।

यह भी ध्यान दें कि ऊपर उल्लिखित एक ही तंत्र का उपयोग प्रत्येक विशेषज्ञता के लिए एक संबद्ध, काल्पनिक फ़ंक्शन टेम्पलेट बनाने और फिर उन फ़ंक्शन टेम्पलेट्स को ऑर्डर करने के माध्यम से क्लास टेम्पलेट के आंशिक विशेषज्ञता के बीच " अधिक विशिष्ट-से अधिक " ऑर्डर करने के लिए किया जाता है। इस जवाब में वर्णित एल्गोरिदम।

यह C ++ 11 मानक के अनुच्छेद 14.5.5.2/1 द्वारा निर्दिष्ट किया गया है:

दो वर्ग टेम्पलेट आंशिक विशेषज्ञता के लिए, सबसे पहले कम से कम दूसरे के रूप में विशिष्ट है, यदि दो फ़ंक्शन टेम्पलेट्स को निम्न पुनर्लेखन दिया गया है, तो पहला फ़ंक्शन टेम्पलेट कम से कम फ़ंक्शन टेम्पलेट्स के लिए ऑर्डर नियमों के अनुसार दूसरे के रूप में विशिष्ट है (14.5 .6.2):

- पहले फ़ंक्शन टेम्पलेट में पहले आंशिक विशेषज्ञता के समान टेम्पलेट पैरामीटर होते हैं और इसमें एक एकल फ़ंक्शन पैरामीटर होता है जिसका प्रकार प्रथम आंशिक विशेषज्ञता के टेम्पलेट तर्कों के साथ एक क्लास टेम्पलेट विशेषज्ञता है, और

- दूसरे फ़ंक्शन टेम्पलेट में दूसरे आंशिक विशेषज्ञता के समान टेम्पलेट पैरामीटर हैं और इसमें एक एकल फ़ंक्शन पैरामीटर है जिसका प्रकार दूसरे आंशिक विशेषज्ञता के टेम्पलेट तर्कों के साथ एक क्लास टेम्पलेट विशेषज्ञता है।

उम्मीद है कि यह मदद की।

मैंने c ++ 11 मानक के बारे में पढ़ा है लेकिन निम्न की मेनिंग अच्छी तरह से समझ नहीं सकता है। उदाहरण बहुत पसंद किया जाता है।

आंशिक क्रम निर्धारित करने के लिए प्रकार के दो सेट का उपयोग किया जाता है। शामिल प्रत्येक टेम्पलेट्स के लिए मूल फ़ंक्शन प्रकार और रूपांतरित फ़ंक्शन प्रकार है। [नोट: रूपांतरित प्रकार का निर्माण 14.5.6.2 में वर्णित है। - अंत नोट] कटौती प्रक्रिया रूपांतरित प्रकार का उपयोग टेम्पलेट टेम्पलेट के रूप में तर्क टेम्पलेट और अन्य टेम्पलेट के मूल प्रकार के रूप में करता है। आंशिक क्रम तुलना में शामिल प्रत्येक प्रकार के लिए यह प्रक्रिया दो बार की जाती है: एक बार ट्रांसफॉर्म किए गए टेम्पलेट -1 को तर्क टेम्पलेट और टेम्पलेट -2 के रूप में पैरामीटर टेम्पलेट के रूप में उपयोग करके और फिर टेम्पलेट टेम्पलेट और टेम्पलेट -1 के रूप में परिवर्तित टेम्पलेट -2 का उपयोग करके पैरामीटर टेम्पलेट के रूप में
- एन 3242 14.8.2.4.2





template-deduction