2017-09-19 25 views
14
template <typename T> 
T go(T a, T *b){ T *t; return *t;} 

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

संकलक त्रुटि देता है?खाका तर्क कटौती विफलता जबकि स्थिरांक प्रकार का पता गुजर

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

उत्तर

13

यह कटौती प्रकार का एक संघर्ष है। 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 केवल हो जाएगा दूसरे तर्क से deducible, और पहला पैरामीटर संशोधन के बिना T का उपयोग करेगा।

+1

धन्यवाद, कि दिलचस्प है, लेकिन आपको लगता है कि चाल वह आंतरिक रूप से करता है पर विचार एक अच्छा प्रोग्रामिंग अभ्यास किया जाएगा है। –

+0

@ सौरवसाहू एक बार जब आप टेम्पलेट्स के साथ अनौपचारिक चीजें करना शुरू कर देते हैं, तो आपको लगता है कि ऐसा कोई 'गैर-प्रेरित' होना आवश्यक है। और एक बार जब आप इसे प्राप्त कर लेंगे, तो आप इसका भी उपयोग कर सकते हैं। चाहे यह इस विशेष मामले में एक अच्छा विचार हो, या क्या चीजें अलग-अलग की जा सकती हैं, वास्तव में आपके असली उपयोग मामले में वास्तव में क्या होता है, इस पर निर्भर करता है। – Angew

6

क्योंकि atemplate argument deduction में, मूल्य द्वारा प्रदान किया जाने वाला तो घोषित किया जाता है:

c) otherwise, if A is a cv-qualified type, the top-level cv-qualifiers are ignored for deduction:

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


Btw: clang इसके लिए काफी स्पष्ट संदेश देता है:

prog.cc:4:3: note: candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'const int')

+0

मुझे लगता है कि ओपी अंतर्दृष्टि तक पहुंच गया है कि क्लैंग संदेश देता है। उन्होंने पूछा कि यह क्यों होता है – sehe

+0

@sehe ऐसा लगता है कि ओपी त्रुटि संदेश के * गलत * भाग पर केंद्रित है; मैं ओपी को बताना चाहता हूं कि टेम्पलेट कटौती के बारे में त्रुटि संदेश अधिक मदद करेगा। – songyuanyao

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