मैं वर्तमान में पढ़ रहा हूँ "प्रभावी सी ++" और वहाँ एक अध्याय है कि इस के लिए कोड समान होता है टाइपकास्ट करने के लिए एक टेम्पलेट वर्ग के लिए दोस्त को जोड़ने:सी ++ क्रम
template <typename T>
class Num {
public:
Num(int n) { ... }
};
template <typename T>
Num<T> operator*(const Num<T>& lhs, const Num<T>& rhs) { ... }
Num<int> n = 5 * Num<int>(10);
पुस्तक का कहना है कि इस नहीं होगा काम (और वास्तव में यह नहीं करता है) क्योंकि आप संकलक को टेम्पलेट विशेषज्ञ बनाने के लिए अंतर्निहित टाइपकास्टिंग का उपयोग करने की अपेक्षा नहीं कर सकते हैं।
एक हलचल के रूप में कक्षा के अंदर समारोह को परिभाषित करने के लिए "मित्र" वाक्यविन्यास का उपयोग करने का सुझाव दिया जाता है।
//It works
template <typename T>
class Num {
public:
Num(int n) { ... }
friend
Num operator*(const Num& lhs, const Num& rhs) { ... }
};
Num<int> n = 5 * Num<int>(10);
और जब भी मुझे टेम्पलेट क्लास प्रकार में निहित रूपांतरण की आवश्यकता होती है तो पुस्तक इस मित्र-घोषणा की चीज़ का उपयोग करने का सुझाव देती है। और यह सब समझ में आता है।
लेकिन मैं एक सामान्य समारोह के साथ काम करने वाला एक ही उदाहरण क्यों नहीं प्राप्त कर सकता, ऑपरेटर नहीं?
template <typename T>
class Num {
public:
Num(int n) { ... }
friend
void doFoo(const Num& lhs) { ... }
};
doFoo(5);
इस बार संकलक शिकायतें कि उन्हें कोई भी 'डूफू' नहीं मिल रहा है। और यदि मैं कक्षा के बाहर डूफू घोषित करता हूं, तो मुझे उचित मिलान प्रकार की त्रुटि मिलती है। ऐसा लगता है कि "दोस्त ..." भाग को अनदेखा किया जा रहा है।
तो क्या मेरी समझ में कोई समस्या है? इस मामले में एक समारोह और ऑपरेटर के बीच क्या अंतर है?
सूचना कैसे की 'ऑपरेटर *' कम से कम एक तर्क एक 'अंक' होना चाहिए। यह 'doFoo' के लिए मामला नहीं है। आपका प्रकार 'int' से' int' के बिना 'int' से रचनात्मक हो सकता है। मजा यह है कि यह तब भी काम नहीं करेगा यदि आपके कनवर्ट करने वाले कन्स्ट्रक्टर क्लास टेम्पलेट के टेम्पलेट तर्कों के साथ पत्राचार करते हैं। आप उस टेम्पलेट के सदस्य फ़ंक्शन के माध्यम से क्लास टेम्पलेट तर्क को कम नहीं कर सकते हैं। आप 'make_num' फ़ंक्शन प्रदान करके उसके आस-पास जा सकते हैं। –
pmr