7

क्या किसी भी तरह से आंशिक टेम्पलेट विनिर्देश को मित्र वर्ग बनाना संभव है? अर्थात। विचार आप निम्नलिखित टेम्पलेट वर्गसी ++ टेम्पलेट्स: आंशिक टेम्पलेट विनिर्देशों और मित्र वर्ग

template <class T> class X{ 
    T t; 
}; 

अब आप आंशिक विशेषज्ञताओं है, उदाहरण के लिए, संकेत के लिए है

template <class T> class X<T*>{ 
    T* t; 
}; 

क्या मैं करना चाहते है कि हर संभव X<T*> किसी के लिए X<S> के एक दोस्त वर्ग है S। अर्थात। X<A*>X<B> का मित्र होना चाहिए।

बेशक

, मैं के बारे में एक्स में एक सामान्य टेम्पलेट दोस्त घोषणा सोचा:

template <class T> class X{ 
    template <class S> friend class X<S*>; 
} 

बहरहाल, यह संकलन नहीं करता है, जी ++ मुझे यह बताता है:

test4.cpp: 34: 15: त्रुटि : 'template<class T> class X' की विशेषज्ञता नाम स्थान दायरे में दिखाई देना चाहिए

test4.cpp: 34: 21: त्रुटि: आंशिक विशेषज्ञता 'X<S*>' घोषित 'मित्र'

क्या यह बिल्कुल संभव नहीं है या क्या कुछ कामकाज है?

कारण है कि मैं पूछ रहा हूँ कि मैं X<T*> में एक निर्माता है कि एक मनमाना X<S> से इस वर्ग बनाता है (ST की एक उप-प्रकार होना चाहिए) की जरूरत है।

कोड इस तरह दिखता है:

template <class T> class X<T*>{ 
    T* t; 

    template<class S> 
    X(X<S> x) : t(&(x.t)) {} //Error, x.t is private 
} 

अब, संकलक ज़ाहिर है, की शिकायत है कि x.t के बाद से यह निजी है निर्माता में दृश्यमान नहीं है। यही कारण है कि मुझे आंशिक विशेषज्ञता मित्र वर्ग की आवश्यकता है।

+1

क्या वास्तव में प्रश्न से बाहर 'get' फ़ंक्शन है? यह मेरे लिए बहुत साफ दिखता है और सभी टेम्पलेट मित्र पागलपन से बचाता है। – pmr

+0

यह शायद इस उदाहरण में काम करेगा। हालांकि, ऐसा डेटा हो सकता है जो जनता के सामने नहीं आना चाहिए बल्कि केवल टेम्पलेट विशेषज्ञता के लिए। सवाल यह है कि अगर यह व्यवहार किसी भी तरह से संभव है। – gexicide

उत्तर

3

सी ++ में, आप चार स्तरों पर private से अधिक पहुंच प्रदान कर सकते हैं।

  • पूरी तरह से public पहुँच वंशानुगत पदानुक्रम के भीतर
  • एक्सेस (protected, यहाँ अप्रासंगिक) एक आधार टेम्पलेट friend को (PMR के जवाब देखें)
  • एक गैर टेम्पलेट या पूरी तरह से करने के लिए
  • (इस उत्तर देखें) (आपके उपयोग के मामले को सुलझाने के लिए बहुत कमजोर) विशेष friend

कोई मध्यम मार्ग शर्त नहीं है दो बार दोस्ती की तरह बुनाई।

सी ++ मानक के §14.5.4 से:।

Friend declarations shall not declare partial specializations.

निम्नलिखित घोषणा आपको जो चाहिए उसे लागू करने की अनुमति देगी। यह आपको किसी भी अन्य विशेषज्ञता से अपने टेम्पलेट के किसी भी विशेषज्ञता तक पहुंचने के लिए एक स्वतंत्र हाथ देता है, लेकिन फिर भी केवल X के भीतर। आपने जो पूछा उससे थोड़ा अधिक अनुमोदित है।

template<class T> class X 
{ 
    template<class Any> friend class X; 
    public: 
     ... 
}; 
1

हम एक getter एक प्रमुख द्वारा संरक्षित एक्स

#include <type_traits> 

template <class T> class X{ 
    T t; 
public: 
    struct Key { 
    template<typename S> 
    Key(const X<S>&) { 
     static_assert(std::is_pointer<S>::value, "Not a pointer"); 
    } 
    }; 

    const T& get(Key) const { return t; } 
    T& get(Key) { return t; } 
}; 

template <class T> class X<T*> { 
    T* t; 
public: 
    template<class S> 
    X(X<S>& x) : t(&(x.get(typename X<S>::Key(*this)))) {} 
}; 

int main() 
{ 
    X<int> x1; 
    X<int*> x2(x1); 
    return 0; 
} 

में परिभाषित किया गया यह अब भी कुछ कमजोरी है परिभाषित कर सकते हैं। X<T*> वाले सभी लोग अब get का उपयोग कर सकते हैं। लेकिन अब तक यह इतनी परेशान है कि कोई भी पर जाने वाला नहीं है। मैं एक साधारण सार्वजनिक गेटटर चुनूंगा।

+1

असल में, 'nullptr' वाला हर कोई 'get' का उपयोग कर सकता है। ऐसा लगता है कि हमारे पास यहां परमिट की प्रतियोगिता है। –

+0

@ जिर्का हनिका आप इसे 'null_ptr' अधिभार के साथ हल करने का प्रयास कर सकते हैं, लेकिन इससे कोई भी बेहतर नहीं होगा। – pmr

+1

हां, '0' शाब्दिक वाला हर कोई अभी भी 'get' का उपयोग कर सकता है। –

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