2012-10-09 30 views
7

में विशिष्ट टेम्पलेट मैत्री, मेरे पास सी ++ में विशिष्ट टेम्पलेट मैत्री के लिए एक प्रश्न है। पुस्तक सी ++ प्राइमर में , विशिष्ट टेम्पलेट दोस्ती इस तरह लिखा है:सी ++

template <class T> class Foo3; 
template <class T> void templ_fcn3(const T&); 
template <class Type> class Bar { 
    // each instantiation of Bar grants access to the 
    // version of Foo3 or templ_fcn3 instantiated with the same type 
    friend class Foo3<Type>; 
    friend void templ_fcn3<Type>(const Type&); 
    // ... 
}; 

विशेष बात यह है कि वहाँ

<Type> 
दोस्त बयान में वर्ग या समारोह के नाम के बाद

है।

हालाँकि, व्यवहार में, अगर मैं लिखना इस:

template <class Type> class T_CheckPointer; 
template <class T> T_CheckPointer<T> operator+(const T_CheckPointer<T> &, const size_t n); 

template <typename Type> 
class T_CheckPointer { 

    // Specific Template Friendship 
    friend T_CheckPointer<Type> 
    operator+ <Type> (const T_CheckPointer<Type> &, const size_t n); 

// other code... 

} 

वहाँ एक त्रुटि टेम्पलेट समारोह के लिए instantiations दौरान किया जाएगा।

और अगर मैं समारोह के नाम के बाद शब्द प्रकार हटा कर

// Specific Template Friendship 
friend T_CheckPointer<Type> 
    operator+ <Type> (const T_CheckPointer<Type> &, const size_t n); 

बदलने

// Specific Template Friendship 
friend T_CheckPointer<Type> 
    operator+ <> (const T_CheckPointer<Type> &, const size_t n); 

है, तो सब ठीक हो जाएगा।

कोई मुझे कारण बता सकता है?


जानकारी के लिए, वहाँ त्रुटि संदेश है जब मैं

int iarr[] = {1, 2, 3, 4}; 
T_CheckPointer<int> itcp(iarr, iarr+4); 

त्रुटि संदेश फोन:

/usr/include/c++/4.4/bits/stl_iterator_base_types.h: In instantiation of ‘std::iterator_traits<int>’: 
/usr/include/c++/4.4/bits/stl_iterator.h:96: instantiated from ‘std::reverse_iterator<int>’ 
../Classes/T_CheckPointer.hpp:31: instantiated from ‘T_CheckPointer<int>’ 
../PE16.cpp:520: instantiated from here 
/usr/include/c++/4.4/bits/stl_iterator_base_types.h:127: error: ‘int’ is not a class, struct, or union type 
/usr/include/c++/4.4/bits/stl_iterator_base_types.h:128: error: ‘int’ is not a class, struct, or union type 
/usr/include/c++/4.4/bits/stl_iterator_base_types.h:129: error: ‘int’ is not a class, struct, or union type 
/usr/include/c++/4.4/bits/stl_iterator_base_types.h:130: error: ‘int’ is not a class, struct, or union type 
/usr/include/c++/4.4/bits/stl_iterator_base_types.h:131: error: ‘int’ is not a class, struct, or union type 
+0

त्रुटि संदेश क्या है? – enobayram

+0

@enobayram, आपके ध्यान के लिए धन्यवाद, मैंने उन्हें लेख में रखा है। – Tianyi

+0

क्या आप ** न्यूनतम ** उदाहरण प्रदान कर सकते हैं (जो कि उदाहरण पर संकलित करता हैविचार) जो समस्या प्रदर्शित करता है? और क्या आपने जीसीसी 4.7 में अपग्रेड करने का प्रयास किया? – TemplateRex

उत्तर

4

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

template<typename T> struct U { typedef typename T::X X; }; 
template<typename T> void foo(typename U<T>::X); 

template<typename T> struct S; 
template<typename T> void foo(S<T>); 
template<typename T> struct S { friend void foo<T>(S<T>); }; 

template struct S<int>; 

friend घोषणा विफल होने का कारण यह है कि टेम्पलेट तर्कों की पूरी सूची प्रदान करके आप संकलक से अनुरोध कर रहे हैं कि सभी उपलब्ध फ़ंक्शन टेम्पलेट्स विशेषज्ञ हों और हस्ताक्षर से सर्वोत्तम मिलान करें। foo की पहली परिभाषा का विशेषज्ञता U को एक तर्क के साथ विशेषज्ञता देता है जिसके परिणामस्वरूप एक बीमार गठित कार्यक्रम होता है।

यदि आप टेम्पलेट तर्क को छोड़ देते हैं, तो यह तर्कों से लिया जाएगा। चूंकि इस तरह के टेम्पलेट तर्क कटौती 14.8.2 [temp.deduct] के अनुसार किया जाता है, और विशेष रूप से 14.8.2p8 लागू होता है, जिसका अर्थ है कि U की विशेषज्ञता में प्रतिस्थापन विफलता एक त्रुटि (SFINAE) नहीं है।

टेम्पलेट तर्कों को छोड़ने के लिए यह एक अच्छा कारण है जहां उन्हें संदर्भ से हटाया जा सकता है (उदाहरण के लिए यहां फ़ंक्शन या ऑपरेटर पैरामीटर प्रकार)। ध्यान दें कि operator + को टेम्पलेट-आईडी (14.5.4 [temp.friend]) के रूप में पढ़ने के लिए आपको अभी भी <> ब्रैकेट प्रदान करने की आवश्यकता है।

+0

+1 यह वास्तव में एक महान जवाब है! यह भी ध्यान रखें कि '<> 'ब्रैकेट टेम्पलेट फ़ंक्शंस के बजाय गैर-टेम्पलेट फ़ंक्शंस को चुनने के लिए हैं। हर्ब सटर द्वारा इस पुराने कॉलम को देखें http://www.drdobbs.com/befriending-templates/184403853 – TemplateRex

+0

+1 आपकी प्रतिक्रिया के लिए बहुत बहुत धन्यवाद! आपका जवाब बहुत स्पष्ट है। @ecatmur – Tianyi