c++ - कंस्ट्रक्ट प्रकार का पता करते हुए टेम्पलेट आर्गुमेंट कटौती विफलता




templates compiler-errors (2)

template <typename T>
T go(T a, T *b){ T *t; return *t;}

int main() {
    const int x = 10;
    go(x, &x);
    return 0;
}

कंपाइलर त्रुटि देता है:

त्रुटि: कॉल करने के लिए कॉल करने के लिए कोई मेल नहीं खाता (const int और, const * *)

पहली तर्क एक संदर्भ प्रकार const int& बस const int बजाय?

इस संकलन त्रुटि को ठीक करने के लिए, मैं तर्कसंगत प्रकार go<const int>(x, &x); को निर्दिष्ट करके संकलक कटौती प्रक्रिया को ओवरराइड करता हूं go<const int>(x, &x); , लेकिन फिर मुझे ऐसा करने की आवश्यकता क्यों है?


क्योंकि a को मान से पारित करने का घोषित किया गया है, फिर टेम्प्लेट में तर्क कटौती :

सी) अन्यथा, अगर ए एक सीवी-योग्य प्रकार है, तो शीर्ष स्तर के सीवी-क्वालिफायर को कटौती के लिए नजरअंदाज किया जाता है:

इसका अर्थ है, go(x, &x); , 1 तर्क x , टेम्प्लेट पैरामीटर T को int रूप में अनुमानित किया जाएगा, const int नहीं। द्वितीय तर्क T लिए कन्वर्ट एट के रूप में अनुमान लगाया जाएगा, क्योंकि b को पॉइंटर (और सीवी-क्वालिफायर को ऑब्जेक्ट पर आरक्षित रखा जाता है; पास-बाय-रेफरेंस के लिए ऐसा ही होता है) फिर कटौती विफल होती है।

बीटीडब्ल्यू: रिंग इसके लिए काफी स्पष्ट संदेश देता है:

prog.cc:4:3: नोट: उम्मीदवार टेम्पलेट को नजरअंदाज कर दिया गया: पैरामीटर 'टी' ('इंट' बनाम 'कॉन्स्ट इंट') के लिए निषिद्ध विवादित प्रकार


यह प्रकार कटौती का एक संघर्ष है T को पहली तर्क से int रूप में अनुमानित किया जाता है, और दूसरे तर्क से const int रूप में। इस प्रकार प्रकार कटौती विफल हो जाती है (और कंपाइलर एक संदेश प्रस्तुत करता है जो अंतर्निहित कारण स्पष्ट कर सकता है या नहीं)।

यदि आप स्पष्ट रूप से टेम्पलेट तर्क निर्दिष्ट करने के लिए बिना इस फ़ंक्शन कार्य करना चाहते हैं, तो आप ऐसा कर सकते हैं ताकि केवल दूसरा फ़ंक्शन तर्क कटौती को ड्राइव कर सके:

template <class T>
struct NonDeduced { using type = T; }

template <class T>
T go(typename NonDeduced<T>::type a, T *b) { T *t; return *t; }

इस तरह, T केवल दूसरे तर्क से ही प्रचलित होगा, और पहले पैरामीटर बिना किसी संशोधन के deduced T उपयोग करेगा।







const