2016-08-16 17 views
6

सी ++ मानक 14.8.2 $ 7 का कहना है कि:प्रतिस्थापन टेम्पलेट तर्क कटौती में कैसे काम करता है?

प्रतिस्थापन सभी प्रकार के और भाव कि समारोह प्रकार में और टेम्पलेट पैरामीटर घोषणाओं में उपयोग किया जाता है में होता है। अभिव्यक्तियों में न केवल निरंतर अभिव्यक्तियां होती हैं जो कि सरणी सीमाओं में दिखाई देती हैं या नॉनटाइप टेम्पलेट तर्क के रूप में दिखाई देती हैं, लेकिन sizeof, decltype के अंदर सामान्य अभिव्यक्तियों (यानी गैर-निरंतर अभिव्यक्ति), और अन्य संदर्भ जो गैर-निरंतर अभिव्यक्तियों को अनुमति देते हैं। प्रतिस्थापन शब्दावली क्रम में आता है और जब ऐसी स्थिति में कटौती का कारण बनता है तो विफल रहता है। [नोट: अपवाद विनिर्देशों में समकक्ष प्रतिस्थापन तभी किया जाता है जब अपवाद-विनिर्देश तत्काल हो जाता है, जिस पर प्रतिस्थापन एक अमान्य प्रकार या अभिव्यक्ति में परिणामस्वरूप एक प्रोग्राम खराब हो जाता है। - अंत टिप्पणी]

मानक यहाँ एक उदाहरण देता है:

template <class T> struct A { using X = typename T::X; }; 
template <class T> typename T::X f(typename A<T>::X); 
template <class T> void f(...) { } 
template <class T> auto g(typename A<T>::X) -> typename T::X; 
template <class T> void g(...) { } 

void h() { 
    f<int>(0); // OK, substituting return type causes deduction to fail 
    g<int>(0); // error, substituting parameter type instantiates A<int> 
} 

क्यों बुला g<int>(0) एक त्रुटि यहाँ है? क्या पिछला-वापसी-प्रकार T::X प्रतिस्थापन विफलता का कारण नहीं है? टेम्पलेट फ़ंक्शन f और g के बीच क्या अंतर है?

उत्तर

4

प्रमुख बिंदु हैं, पहले,

शाब्दिक क्रम में प्रतिस्थापन आय और जब एक शर्त का कारण बनता है कि कटौती विफल

और दूसरा, का सामना करना पड़ा है बंद हो जाता है A<int> की की इन्स्टेन्शियशन परिभाषा एक कठोर त्रुटि को ट्रिगर करती है, प्रतिस्थापन विफलता नहीं, क्योंकि इसके परिणामस्वरूप तत्काल संदर्भ के बाहर एक बीमार गठित typename T::X (T == int के साथ) को तुरंत चालू किया जाता है। [temp.deduct]/8:

केवल अवैध प्रकार और समारोह प्रकार के तत्काल संदर्भ और उसके टेम्पलेट पैरामीटर प्रकार में भाव एक कटौती विफलता हो सकती है। [नोट: एवजी प्रकार और भाव के मूल्यांकन ऐसे वर्ग टेम्पलेट विशेषज्ञताओं और/या समारोह टेम्पलेट विशेषज्ञताओं, परोक्ष-परिभाषित प्रकार्य की पीढ़ी, आदि इस तरह के साइड इफेक्ट की इन्स्टेन्शियशन के रूप में साइड इफेक्ट हो सकता है "तत्काल संदर्भ" में नहीं हैं और परिणामस्वरूप प्रोग्राम खराब हो रहा है। - अंत टिप्पणी]

मुद्दे पर टेम्पलेट्स के साथ

, एक कटौती की विफलता में समारोह प्रकार के परिणाम (जैसे कि, SFINAE) में typename T::X में प्रतिस्थापन; typename A<T>::X में प्रतिस्थापित करने में कठिनाई होती है। चूंकि प्रतिस्थापन 0xके लिए लेक्सिकल ऑर्डर में आता है, यह पहले typename T::X में बदलता है, जिसके परिणामस्वरूप कटौती विफलता होती है, और आगे प्रतिस्थापन का प्रयास नहीं किया जाता है। दूसरी ओर, template <class T> auto g(typename A<T>::X) -> typename T::X; के लिए, यह पहले typename A<T>::X में प्रतिस्थापित करता है, जिसके परिणामस्वरूप हार्ड त्रुटि होती है।

+0

रिटर्न प्रकार फ़ंक्शन हस्ताक्षर के हिस्से के रूप में कैसे गिना जाता है लेकिन पैरामीटर नहीं? – Barry

+0

@ बैरी मुझे लगता है कि दोनों रिटर्न प्रकार और पैरामीटर को फ़ंक्शन हस्ताक्षर – Carousel

+0

@ बैरी के हिस्से के रूप में माना जाता है। वे फ़ंक्शन टेम्पलेट के हस्ताक्षर का हिस्सा हैं, लेकिन मुझे शायद "हस्ताक्षर" का उपयोग नहीं करना चाहिए। –

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