2012-01-08 29 views
11

सी ++ 03 में, कुछ संदर्भों में टेम्पलेट पैरामीटर कटौती नहीं होती है। उदाहरण के लिए:टेम्पलेट उपनाम टेम्पलेट पैरामीटर कटौती को कैसे प्रभावित करते हैं?

template <typename T> struct B {}; 

template <typename T> 
struct A 
{ 
    typedef B<T> type; 
}; 

template <typename T> 
void f(typename A<T>::type); 

int main() 
{ 
    B<int> b; 
    f(b); // ERROR: no match 
} 

यहाँ, int, T के लिए निष्कर्ष निकाला नहीं है, क्योंकि इस तरह के A<T>::type के रूप में एक नेस्टेड प्रकार एक गैर निष्कर्ष निकाला संदर्भ है।

मैं इस तरह समारोह लिखा था:

template <typename T> struct B {}; 

template <typename T> 
void f(B<T>); 

int main() 
{ 
    B<int> b; 
    f(b); 
} 

सब कुछ ठीक है क्योंकि B<T> एक निष्कर्ष निकाला संदर्भ है।

सी ++ 11 में, हालांकि, टेम्पलेट उपनाम का उपयोग दूसरे उदाहरण के समान वाक्यविन्यास में नेस्टेड प्रकार को छिपाने के लिए किया जा सकता है। उदाहरण के लिए:

template <typename T> struct B {}; 

template <typename T> 
struct A 
{ 
    typedef B<T> type; 
}; 

template <typename T> 
using C = typename A<T>::type; 

template <typename T> 
void f(C<T>); 

int main() 
{ 
    B<int> b; 
    f(b); 
} 

इस मामले में टेम्पलेट तर्क कटौती कार्य करेगा? दूसरे शब्दों में, क्या टेम्पलेट उपरोक्त एक संदर्भित संदर्भ या गैर-कटौती संदर्भ हैं? या क्या वे जो भी उपनाम की कटौती/गैर-कटौती की स्थिति का उत्तराधिकारी हैं?

+1

उपनाम केवल उपनाम हैं। यह 'टेम्पलेट शून्य एफ (टाइपनाम ए :: प्रकार) लिखने जैसा है;', जो deducible नहीं है। –

+0

[सी ++, टेम्पलेट तर्क का संभावित डुप्लिकेट घटाया नहीं जा सकता] [http://stackoverflow.com/questions/6060824/c-template-argument-can-not-be-deduced) – Nawaz

+0

मुझे लगता है कि केरेक एसबी सही है इसके बारे में। अगर उद्धरण प्रदान किया गया था तो मुझे जाने और एक खोज करने की आवश्यकता नहीं होगी ;-) –

उत्तर

8

दूसरे शब्दों में, टेम्पलेट उपनाम एक समर्पित संदर्भ या एक गैर-कटौती संदर्भ हैं?

वे टेम्पलेट उपनामों के बिना समकक्ष कोड के रूप में deducible के रूप में deducible हैं। उदाहरण

लिए
template<typename T> 
using ref = T&; 

template<typename T> 
void f(ref<T> r); 

अब आप f(x) कॉल कर सकते हैं और T बिल्कुल ठीक निष्कर्ष निकाला की जाएगी। f की परिभाषा समय पर पहले से ही ref<T> को T& टाइप किया गया है। और T& एक अनुमानित संदर्भ है।

अपने मामले C<T> में typename A<T>::type ने ले ली है, और कहा कि T के लिए एक गैर निष्कर्ष निकाला संदर्भ है, इसलिए T निष्कर्ष निकाला नहीं जा सकता है।

+1

जोहान्स के उत्कृष्ट उत्तर में मुख्य वाक्यांश "एफ * पहले से ही परिभाषित समय * पर है (जोर मेरा)। इसे याद करना आसान है, लेकिन यह जानना सबकुछ बताता है। –

1

इस कल्पना कीजिए:

template <typename T> struct Foo { typedef T type; } 
template <> struct Foo<char>  { typedef int type; } 

template <typename T> using mytype = typename Foo<T>::type; 

template <typename T> void f(mytype<T>); 

अब अगर मैं int n; f(n); चाहते हैं, मैं कैसे तय कर सकता है कि क्या मैं T = int या T = char करना चाहते हैं? पूरी समस्या, जो टेम्पलेट उपनामों से अप्रभावित है, यह है कि आप पीछे की ओर उन सभी चीजों को घटा सकते हैं जो संभवतः कुछ परिभाषित कर सकते हैं।

1

मुझे लगता है कि सी ++ मानक में प्रासंगिक उद्धरण है 14.5.7 [temp.alias] पैरा 2:

एक टेम्पलेट आईडी एक उपनाम टेम्पलेट की विशेषज्ञता को दर्शाता है, यह के बराबर है उपनाम टेम्पलेट के प्रकार-आईडी में टेम्पलेट-पैरामीटर के लिए अपने टेम्पलेट-तर्कों के प्रतिस्थापन द्वारा प्राप्त संबंधित प्रकार। [नोट: एक उपनाम टेम्पलेट नाम कभी नहीं लिया जाता है। - अंत नोट]

उद्धरण के बाद एक उदाहरण है जो प्रभावी ढंग से बताता है कि फ़ंक्शन टेम्पलेट में उपनाम टेम्पलेट का उपयोग करना और टेम्पलेट तर्क को कम करने की उम्मीद करना व्यर्थ है। यह स्पष्ट रूप से ऐसी स्थिति के लिए भी लागू होता है जिसमें घोंसला वाले प्रकार शामिल नहीं होते हैं।

+0

आपका अंतिम विवरण गलत है। कटौती के संबंध में आपका उद्धरण कहता है कि उपनाम टेम्पलेट नाम को घटाया नहीं जा सकता है। वह 'टेम्पलेट <टेम्पलेट कक्षा सी> शून्य एफ (सी ) है; रेफरी आर; एफ (आर); 'सी == रेफरी 'को कम करना संभव नहीं है (मेरे उत्तर में' रेफरी 'की मेरी परिभाषा दी गई है)। इसका मतलब यह नहीं है कि आप इसका क्या अर्थ उठाते हैं। –

+0

ठीक है, मैं इसे स्वीकार कर सकता हूं। हालांकि, कल मुझे एक बेहतर उद्धरण नहीं मिला है (लेकिन मुझे उलझन में पड़ सकता है)। क्या आप मुझे मानक में उद्धरण की ओर इंगित कर सकते हैं? –

+1

आपने इसे स्वयं उद्धृत किया है। टेम्पलेट-आईडी 'रेफरी 'आपके द्वारा दिए गए उद्धरण के द्वारा' टी एंड 'के बराबर है। और इसलिए गैर-मानदंड नोट कहता है कि 'रेफरी' को कम करने के लिए यह उपयोग करने योग्य नहीं है। लेकिन यह प्रारंभिक प्रतिस्थापन के कारण 'टी' को कम करने के लिए प्रयोग योग्य है। Http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#395 और http://stackoverflow.com/a/6623089/34509 –

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