परिचय: C++ में Generics (टेम्पलेट) क्या हैं और इनकी आवश्यकता क्यों है?
C++ प्रोग्रामिंग की दुनिया में, लचीला, पुन: प्रयोज्य और टाइप-सुरक्षित कोड लिखने में सक्षम बनाने वाली प्रमुख अवधारणाओं में से एक हैं टेम्पलेट (templates)। इन्हें अक्सर Java या C# जैसी अन्य भाषाओं के अनुरूप "generics" कहा जाता है, हालांकि C++ में यह अवधारणा कहीं अधिक शक्तिशाली और गहरी है।
कल्पना करें कि आपको किसी ऐरे में अधिकतम तत्व खोजने के लिए एक फंक्शन लिखना है। पूर्णांकों (int) के लिए एक फंक्शन, फ्लोटिंग-पॉइंट संख्याओं (double) के लिए दूसरा, और स्ट्रिंग्स (std::string) के लिए तीसरा। टेम्पलेट के बिना, आपको कोड को डुप्लिकेट करना होगा, जिससे त्रुटियां होती हैं और रखरखाव जटिल हो जाता है।
Generics (टेम्पलेट) इस समस्या का समाधान करते हैं। वे आपको ऐसा कोड लिखने की अनुमति देते हैं जो किसी भी डेटा प्रकार के साथ काम करता है, बिना प्रदर्शन से समझौता किए (वर्चुअल फंक्शन या void* के विपरीत)। टेम्पलेट C++ स्टैंडर्ड लाइब्रेरी (STL) की नींव हैं: कंटेनर (std::vector, std::map), एल्गोरिदम (std::sort, std::find) और स्मार्ट पॉइंटर्स (std::shared_ptr) — ये सभी टेम्पलेट का उपयोग करके कार्यान्वित किए गए हैं।
इस लेख में, हम समझेंगे कि C++ में टेम्पलेट क्या हैं, उन्हें सही तरीके से कैसे घोषित और उपयोग किया जाए, साथ ही व्यावहारिक उदाहरण भी देखेंगे।
मुख्य भाग: C++ में Generics (टेम्पलेट) का उपयोग कैसे करें
1. फंक्शन टेम्पलेट (Function Templates)
generics के साथ काम शुरू करने का सबसे सरल तरीका फंक्शन टेम्पलेट बनाना है। कई ओवरलोडेड वर्जन लिखने के बजाय, आप एक ऐसा फंक्शन लिखते हैं जो टाइप द्वारा पैरामीटराइज़ किया गया हो।
सिंटैक्स:
template <typename T>T max(T a, T b) { return (a > b) ? a : b;}कीवर्ड template कंपाइलर को बताता है कि यह एक टेम्पलेट है। <typename T> टाइप पैरामीटर T घोषित करता है। आप typename के बजाय class का उपयोग कर सकते हैं — इसमें कोई अंतर नहीं है।
उपयोग का उदाहरण:
#include <iostream>#include <string>
template <typename T>T max(T a, T b) { return (a > b) ? a : b;}
int main() { std::cout << max(10, 20) << std::endl; // int: 20 std::cout << max(3.14, 2.71) << std::endl; // double: 3.14 std::cout << max(std::string("C++"), std::string("Python")) << std::endl; // string: Python return 0;}महत्वपूर्ण: कंपाइलर प्रत्येक उपयोग किए गए टाइप के लिए फंक्शन का एक अलग वर्जन जनरेट करता है। इसे टेम्पलेट इंस्टेंशिएशन कहा जाता है। इसके माध्यम से अधिकतम प्रदर्शन प्राप्त होता है — वर्चुअल कॉल का कोई ओवरहेड नहीं होता।
एकाधिक टाइप पैरामीटर:
template <typename T1, typename T2>void printPair(T1 a, T2 b) { std::cout << "(" << a << ", " << b << ")" << std::endl;}// printPair(1, "hello"); // आउटपुट: (1, hello)2. क्लास टेम्पलेट (Class Templates)
क्लास टेम्पलेट सामान्यीकृत डेटा संरचनाएं बनाने की अनुमति देते हैं। एक उत्कृष्ट उदाहरण है std::vector<T>। आप अपना खुद का टेम्पलेटेड क्लास बना सकते हैं, उदाहरण के लिए, एक सरल स्टैक:
template <typename T>class Stack {private: T* data; size_t size; size_t capacity;public: Stack(size_t cap = 10) : size(0), capacity(cap) { data = new T[capacity]; } ~Stack() { delete[] data; }
void push(const T& value) { if (size < capacity) { data[size++] = value; } }
T pop() { if (size > 0) { return data[--size]; } throw std::out_of_range("Stack is empty"); }
bool isEmpty() const { return size == 0; }};उपयोग:
Stack<int> intStack;intStack.push(10);intStack.push(20);std::cout << intStack.pop() << std::endl; // 20
Stack<std::string> stringStack;stringStack.push("Hello");stringStack.push("World");std::cout << stringStack.pop() << std::endl; // World3. टेम्पलेट विशेषज्ञता (Template Specialization)
कभी-कभी आप किसी विशिष्ट प्रकार के लिए टेम्पलेट का एक अलग व्यवहार चाहते हैं। इसे टेम्पलेट विशेषज्ञता कहा जाता है। उदाहरण के लिए, bool प्रकार के लिए एक विशेष संस्करण:
template <>class Stack<bool> {private: // bool के लिए ऑप्टिमाइज़्ड इम्प्लीमेंटेशन unsigned char* data; size_t size; size_t capacity;public: Stack(size_t cap = 10) : size(0), capacity(cap) { data = new unsigned char[(capacity + 7) / 8]; } ~Stack() { delete[] data; }
void push(bool value) { // विशेष हैंडलिंग }
bool pop() { // विशेष हैंडलिंग return false; }
bool isEmpty() const { return size == 0; }};4. नॉन-टाइप टेम्पलेट पैरामीटर (Non-type Template Parameters)
टेम्पलेट केवल प्रकारों तक सीमित नहीं हैं। आप पूर्णांक, एनम, या पॉइंटर्स को भी पैरामीटर के रूप में पास कर सकते हैं:
template <typename T, int Size>class Array {private: T data[Size];public: int getSize() const { return Size; } T& operator[](int index) { return data[index]; }};
Array<int, 5> arr;arr[0] = 10;std::cout << arr.getSize() << std::endl; // 5निष्कर्ष
C++ में Generics (टेम्पलेट) एक शक्तिशाली उपकरण है जो आपको पुन: प्रयोज्य, टाइप-सुरक्षित और कुशल कोड लिखने की अनुमति देता है। चाहे वह फंक्शन टेम्पलेट हो, क्लास टेम्पलेट, या विशेषज्ञता, वे आधुनिक C++ प्रोग्रामिंग का एक अनिवार्य हिस्सा हैं। STL जैसी लाइब्रेरीज टेम्पलेट पर निर्भर करती हैं, और उन्हें समझना आपको अधिक प्रभावी C++ डेवलपर बनाएगा।
अभ्यास के लिए, अपना खुद का Vector या List टेम्पलेट क्लास बनाने का प्रयास करें, और विभिन्न प्रकारों के साथ इसका परीक्षण करें। टेम्पलेट्स की दुनिया में आपका स्वागत है!