क्लास के भीतर टेम्प्लेट फ़ंक्शन कैसे बनाएं? (C ++)


144

मुझे पता है कि एक खाका समारोह करना संभव है:

template<typename T>
void DoSomeThing(T x){}

और टेम्प्लेट क्लास बनाना संभव है:

template<typename T>
class Object
{
public:
    int x;
};

लेकिन क्या यह संभव है कि कक्षा को टेम्पलेट के भीतर न बनाया जाए, और फिर उस कक्षा को एक टेम्पलेट में एक समारोह बनाया जाए? अर्थात:

//I have no idea if this is right, this is just how I think it would look
class Object
{
public:
    template<class T>
    void DoX(){}
};

या कुछ हद तक, जहां वर्ग टेम्पलेट का हिस्सा नहीं है, लेकिन फ़ंक्शन है?

जवाबों:


115

आपका अनुमान सही है। केवल एक चीज आप को याद करने के लिए है कि सदस्य समारोह टेम्पलेट है परिभाषा (घोषणा के अलावा), हालांकि यह है, प्रवेशिका फ़ाइल, नहीं सीपीपी में होना चाहिए वर्ग घोषणा खुद के शरीर में रहना होगा।


3
और यह भी कि आप उन्हें विशेषज्ञ नहीं बना सकते। :-(
फ्रैंक क्रुएगर

7
बिल्कुल सच नहीं है। परिभाषा एक सीपीपी फ़ाइल में हो सकती है, जब तक कि इसे परिभाषित किए जाने के बाद गैर-टेम्पलेट फ़ंक्शन / विधि से प्रत्येक अद्वितीय टेम्पलेट पैरामीटर n-uplet के लिए एक बार कहा जाता है।
बेनोइट

1
इसलिए मेरा "चाहिए" - इसे हेडर में रखते हुए इसे पूरा करने का सबसे सरल तरीका है।
यकीन नहीं हुआ

4
वास्तव में, मेरा मानना ​​है कि आप स्पष्ट रूप से उन्हें विशेषज्ञ बना सकते हैं, लेकिन आप उन्हें आंशिक रूप से विशेषज्ञ नहीं बना सकते। दुर्भाग्य से मुझे नहीं पता कि यह एक संकलक-विशिष्ट विस्तार है, या C ++ मानक है।
पैट्रिक जॉम्नियर

7
यह वास्तव में मानक सी ++ है। आप संरचना ए {टेम्पलेट <टाइपनेम> शून्य च () कर सकते हैं; }; टेम्पलेट <> void A :: f <int> () {} उदाहरण के लिए। आप सिर्फ उन्हें क्लास स्कोप में विशेषज्ञ नहीं बना सकते हैं, लेकिन जब आप नेमस्पेस स्कोप में किया जाता है तो आप इसे अच्छी तरह से कर सकते हैं। (उस दायरे से भ्रमित न होना जो विशेषज्ञता वास्तव में है: विशेषज्ञता अभी भी वर्ग का एक सदस्य होगी - लेकिन इसकी परिभाषा नाम स्थान के दायरे में की जाती है। अक्सर गुंजाइश जहां कुछ डाल दी जाती है, वह गुंजाइश के समान होती है। कुछ को परिभाषित किया गया है - लेकिन यह कभी-कभी सच नहीं होता है, जैसा कि आउट-ऑफ-क्लास परिभाषाओं के सभी मामलों में होता है)
जोहान्स स्काउब -

70

यहाँ देखें: टेम्प्लेट , टेम्प्लेट मेथड्स , मेंबर टेम्प्लेट्स, मेंबर फंक्शन टेंपलेट्स

class   Vector
{
  int     array[3];

  template <class TVECTOR2> 
  void  eqAdd(TVECTOR2 v2);
};

template <class TVECTOR2>
void    Vector::eqAdd(TVECTOR2 a2)
{
  for (int i(0); i < 3; ++i) array[i] += a2[i];
}

अच्छा उदाहरण। लेकिन क्यों टेम्पलेट <typename T> वर्ग निश्चित के अंदर है ... ???
मंगल १

@ Martian2049 मेरा मानना ​​है कि यह खाका केवल कक्षा के भीतर सदस्य फ़ंक्शन पर लागू होता है, न कि कक्षा को समग्र रूप से। बिल्कुल जैसा कि ओपी ने पूछा।
सीबीके

21

हां, टेम्पलेट सदस्य कार्य कई अवसरों पर पूरी तरह से कानूनी और उपयोगी हैं।

केवल चेतावनी यह है कि टेम्पलेट सदस्य फ़ंक्शन वर्चुअल नहीं हो सकते।


9

सबसे आसान तरीका यह है कि घोषणा और परिभाषा को एक ही फ़ाइल में रखा जाए, लेकिन यह अति-आकार की अति-उपयोगी फ़ाइल हो सकती है। उदाहरण के लिए

class Foo
{
public:
template <typename T> void some_method(T t) {//...}
}

इसके अलावा, टेम्प्लेट की परिभाषा को अलग-अलग फ़ाइलों में रखना संभव है, अर्थात उन्हें .cpp और .h फ़ाइलों में रखना। आपको केवल स्पष्ट रूप से .cpp फ़ाइलों के टेम्प्लेट इंस्टेंटेशन को शामिल करना है। उदाहरण के लिए

// .h file
class Foo
{
public:
template <typename T> void some_method(T t);
}

// .cpp file
//...
template <typename T> void Foo::some_method(T t) 
{//...}
//...

template void Foo::some_method<int>(int);
template void Foo::some_method<double>(double);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.