7

अन्य टेम्पलेट की एक डमी पैरामीटर के अंदर एक मामले में जहां एक-दूसरे टेम्पलेट g के साथ एक प्रकार T को सत्यापित करना होगा पर विचार करें (कुछ enable_if अभिव्यक्ति हो सकता है, उदाहरण के लिए), इस तरह:अस्पष्ट टेम्पलेट

template<class>  struct g { typedef void type; }; 
template<class, class> struct f {}; 
template<class T>  struct f<T, void> {};     // Case A 
template<class T>  struct f<T*, typename g<T>::type> {}; // Case B 

int main() { f<int*, void> test; } 

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

डमी पैरामीटर हटा दिया जाना चाहिए थे, तो यह ठीक संकलित करता है। कैसे एक nondeduced पैरामीटर किसी भी तरह के अलावा उचित अपेक्षा को नष्ट करता है कि T*T की तुलना में अधिक विशिष्ट है?

f<Q , void  > 
-> f<T*, g<Q>::type> // [failed] 

    f<Q*, g<Q>::type> 
-> f<T , void  > // [to fail or not to fail?] 
// One would assume that 2nd parameter is ignored, but guess not? 

उत्तर

5

जब अस्पष्टता पैदा होती है, टेम्पलेट्स के आंशिक आदेश इसे सुलझाने के लिए प्रयोग किया जाता है:

यहाँ एक त्वरित जांच प्रतिस्थापन कलन विधि का उपयोग है। बहरहाल, यह आंशिक आदेश टेम्पलेट्स पर स्थापित है वे कर रहे हैं के रूप में से पहले किसी भी प्रतिस्थापन होता है, और नहीं के बाद (आंशिक या पूर्ण) प्रतिस्थापन निष्पादित किया गया है - है जो आप, typename g<T>::type में T के लिए int की जगह उम्मीद कर रहे हैं जो void (के g परिभाषा की वजह से) पैदावार typename g<int>::type और इसलिए।

पैरा 14.8.2.4/2 निर्दिष्ट करता है कि आंशिक आदेश स्थापित है (नीचे पैरा के एक अधिक विस्तृत चर्चा के लिए this answer on SO देखें):

प्रकार के

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

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

दूसरे शब्दों में, सवाल है:

template<class T> struct f<T, void>; // Case A 

इस एक से अधिक विशेष है (आंशिक प्रतिस्थापन के माध्यम से प्राप्त):

template<class T> struct f<T*, void>; // Case B 

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

template<class T> struct f<T, void>; // Case A 

अधिक विशिष्ट से यह एक है: इसके बजाय, सवाल किसी भी संभव T, इस विशेषज्ञता के लिए है कि क्या है

template<class T> struct f<T*, typename g<T>::type>; // Case B 

कि चूंकि किसी भी T के लिए स्थापित नहीं किया जा सकता, मामले बी है न केस ए से अधिक विशिष्ट और न ही कम विशेष, और जब दोनों व्यवहार्य हैं, तो आपको अस्पष्टता मिलती है।

ज्यादातर मामलों में, सभी टेम्पलेट:

अगर आप सोच रहे हैं कि क्या एक गैर निष्कर्ष निकाला संदर्भ में मानकों आंशिक आदेश देने के लिए ध्यान में रखा जाता है, यह एक नोट में अनुच्छेद 14.8.2.4/11 को बताया गया है मानदंडों को सफल होने के लिए मानदंडों के क्रम में होना चाहिए, लेकिन आंशिक ऑर्डर करने के उद्देश्यों के लिए एक टेम्पलेट पैरामीटर किसी मान के बिना रह सकता है बशर्ते इसे प्रकारों में आंशिक क्रम के लिए उपयोग नहीं किया जा रहा है। [नोट: गैर-कट किए गए संदर्भ में उपयोग किए गए टेम्पलेट पैरामीटर को माना जाता है। अंत ध्यान दें]

+0

मुझे पता है कि प्रतिस्थापन इस में एक भूमिका निभा नहीं करता था, लेकिन क्यों एक आश्रित प्रकार अभी भी आंशिक आदेश एल्गोरिथ्म में माना जाता है के साथ एक पैरामीटर (मैं यह उम्मीद होने के लिए मैं मुख्य रूप से हैरान था अवहेलना करना)। – Rufflewind

+0

@fzlogic: "क्यों" एक गैर-रचनात्मक प्रश्न है जो मुझे डरता है :) लेकिन तथ्य यह है कि उन्हें मानक द्वारा स्पष्ट रूप से निर्दिष्ट किया जाना चाहिए (उत्तर के अंत में उद्धृत उद्धरण देखें) –

+0

मानक से उद्धरण वह था जिसे मैं अपने "क्यों" प्रश्न के संबंध में ढूंढ रहा था। शुक्र है, कामकाज काफी आसान था: ** केस ए ** में 'शून्य' को एक मनमाना प्रकार के रूप में बदलें। – Rufflewind

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