परिचय: C++ में generics क्या हैं और इनकी आवश्यकता क्यों है
\nआधुनिक प्रोग्रामिंग की दुनिया में, कोड का पुन: उपयोग प्रमुख सिद्धांतों में से एक है। यदि आप int के लिए योग फलन लिखते हैं, और फिर double और float के लिए, तो देर-सबेर आप दोहराव से बचना चाहेंगे। यहीं पर generics (सामान्यीकृत प्रोग्रामिंग) काम आते हैं। C++ में यह अवधारणा टेम्पलेट (templates) के माध्यम से कार्यान्वित की जाती है।
Generics आपको ऐसा कोड लिखने की अनुमति देते हैं जो किसी भी डेटा प्रकार के साथ काम करता है, बिना प्रदर्शन से समझौता किए (वर्चुअल फलन या void* के विपरीत)। कंपाइलर प्रत्येक विशिष्ट प्रकार के लिए फलन या वर्ग का एक अलग संस्करण उत्पन्न करता है, जो अधिकतम निष्पादन गति प्रदान करता है।
इस लेख में, हम समझेंगे कि C++ में generics की आवश्यकता क्यों है, उन्हें सही तरीके से कैसे घोषित और व्यवहार में उपयोग किया जाए, साथ ही सामान्य गलतियों और उन्नत तकनीकों पर भी चर्चा करेंगे।
\n\nसिंटैक्स की मूल बातें: टेम्पलेट कैसे घोषित और उपयोग करें
\nC++ में टेम्पलेट को कीवर्ड template और कोण कोष्ठक <> के साथ घोषित किया जाता है, जिसके अंदर पैरामीटर-प्रकार (आमतौर पर typename या class) निर्दिष्ट किया जाता है।
फलन-टेम्पलेट
\nसबसे सरल उदाहरण एक फलन है जो दो मानों में से अधिकतम लौटाता है:
\ntemplate <typename T>\nT max(T a, T b) {\n return (a > b) ? a : b;\n}\n\n// उपयोग:\nint main() {\n std::cout << max(3, 7) << std::endl; // 7\n std::cout << max(3.14, 2.71) << std::endl; // 3.14\n std::cout << max('a', 'z') << std::endl; // z\n return 0;\n}\nध्यान दें: कंपाइलर पारित तर्कों के आधार पर स्वचालित रूप से T प्रकार का अनुमान लगाता है। यदि आपको स्पष्ट रूप से प्रकार निर्दिष्ट करने की आवश्यकता है, तो आप max<double>(3.14, 2.71) लिख सकते हैं।
वर्ग-टेम्पलेट
\nटेम्पलेट वर्गों के साथ भी काम करते हैं। एक उत्कृष्ट उदाहरण एक सरल "जोड़ी" कंटेनर है:
\ntemplate <typename T1, typename T2>\nclass Pair {\nprivate:\n T1 first;\n T2 second;\npublic:\n Pair(T1 f, T2 s) : first(f), second(s) {}\n T1 getFirst() const { return first; }\n T2 getSecond() const { return second; }\n};\n\n// उपयोग:\nPair<int, std::string> student(1, "Alice");\nstd::cout << student.getFirst() << " " << student.getSecond();\nयहाँ T1 और T2 टेम्पलेट पैरामीटर हैं, जो कोई भी प्रकार हो सकते हैं।
व्यावहारिक उदाहरण: सरल कंटेनरों से लेकर एल्गोरिदम तक
\nआइए कुछ वास्तविक परिदृश्यों पर विचार करें जहाँ generics अपरिहार्य हैं।
\n\nसार्वभौमिक सॉर्टिंग
\nआइए किसी भी प्रकार की सरणी को सॉर्ट करने के लिए एक टेम्पलेट फलन लिखें जो < ऑपरेटर का समर्थन करता है:
template <typename T>\nvoid bubbleSort(T arr[], int n) {\n for (int i = 0; i < n - 1; ++i)\n for (int j = 0; j < n - i - 1; ++j)\n if (arr[j] > arr[j + 1])\n std::swap(arr[j], arr[j + 1]);\n}\n\n// उदाहरण:\nint intArr[] = {5, 2, 8, 1};\nbubbleSort(intArr, 4); // int के साथ काम करता है\n\ndouble dblArr[] = {3.14, 2.71, 1.41};\nbubbleSort(dblArr, 3); // double के साथ काम करता है\n\nमनमाना डेटा प्रकार वाला स्टैक
\nआइए टेम्पलेट के आधार पर एक सरल स्टैक लागू करें:
\ntemplate <typename T>\nclass Stack {\nprivate:\n std::vector<T> elements;\npublic:\n void push(const T& value) { elements.push_back(value); }\n void pop() { if (!elements.empty()) elements.pop_back(); }\n T top() const { return elements.back(); }\n bool empty() const { return elements.empty(); }\n};\n\n// उपयोग:\nStack<int> intStack;\nintStack.push(10);\nintStack.push(20);\nstd::cout << intStack.top(); // 20\n\n"खोजें और बदलें" एल्गोरिदम
\nएक टेम्पलेट फलन जो कंटेनर में एक मान के सभी उदाहरणों को दूसरे मान से बदल देता है:
\ntempla