C++ में जेनेरिक्स: इनकी आवश्यकता और उपयोग कैसे करें
\n\nहर प्रोग्रामर को देर-सबेर ऐसी स्थिति का सामना करना पड़ता है जहाँ उन्हें एक ऐसा फ़ंक्शन लिखना होता है जो विभिन्न डेटा प्रकारों के साथ काम करता है। उदाहरण के लिए, अधिकतम तत्व खोजने का फ़ंक्शन - इसे int, double और string सभी के साथ समान रूप से अच्छी तरह से काम करना चाहिए। विशेष साधनों के बिना, प्रत्येक प्रकार के लिए अलग-अलग कार्यान्वयन लिखना होगा। यहीं पर जेनेरिक्स (सामान्यीकृत प्रकार) या, जैसा कि C++ में कहा जाता है, टेम्पलेट मदद करते हैं।
C++ में, टेम्पलेट तंत्र सामान्यीकृत प्रोग्रामिंग का आधार है। यह आपको ऐसा कोड लिखने की अनुमति देता है जो प्रदर्शन से समझौता किए बिना किसी भी डेटा प्रकार के साथ काम करता है। इस लेख में, हम समझेंगे कि C++ में जेनेरिक्स क्या हैं, इनकी आवश्यकता क्यों है, और व्यवहार में इनका उपयोग कैसे करें। यह सामग्री शुरुआती लोगों के लिए है, इसलिए हम सरल से जटिल की ओर बढ़ेंगे।
\n\nC++ में टेम्पलेट (जेनेरिक्स) क्या हैं?
\n\nटेम्पलेट एक ऐसी संरचना है जो आपको एक फ़ंक्शन या क्लास को परिभाषित करने की अनुमति देती है जो किसी भी डेटा प्रकार के साथ काम करता है। किसी विशिष्ट प्रकार के बजाय, आप एक प्रकार पैरामीटर (जैसे, T) निर्दिष्ट करते हैं, और कंपाइलर संकलन के समय आवश्यक प्रकार को प्रतिस्थापित करता है। इसे टेम्पलेट इंस्टेंशिएशन कहा जाता है।
कुकीज़ पकाने के लिए एक साँचे की कल्पना करें। साँचा एक है, लेकिन कुकीज़ विभिन्न आटे से बनाई जा सकती हैं: शॉर्टब्रेड, चॉकलेट, ओटमील। टेम्पलेट साँचा है, और प्रकार (int, double, string) आटा है। आप एक बार एल्गोरिथ्म का वर्णन करते हैं, और कंपाइलर स्वचालित रूप से आवश्यक प्रकारों के लिए संस्करण बनाता है।
\n\nटेम्पलेट दो प्रकार के होते हैं:
\n- \n
- फ़ंक्शन टेम्पलेट — सामान्यीकृत फ़ंक्शन बनाने के लिए। \n
- क्लास टेम्पलेट — सामान्यीकृत क्लास (जैसे, कंटेनर) बनाने के लिए। \n
फ़ंक्शन टेम्पलेट: सामान्यीकृत कोड की ओर पहला कदम
\n\nचलिए सबसे सरल चीज़ से शुरू करते हैं — एक टेम्पलेट फ़ंक्शन। मान लीजिए हमें एक ऐसे फ़ंक्शन की आवश्यकता है जो दो मानों में से अधिकतम लौटाता है। बिना टेम्पलेट के यह इस प्रकार दिखता है:
\n\nint max_int(int a, int b) {\n return (a > b) ? a : b;\n}\n\ndouble max_double(double a, double b) {\n return (a > b) ? a : b;\n}\n\nकोड दोहराया जा रहा है। टेम्पलेट के साथ, इसे सुरुचिपूर्ण ढंग से हल किया जाता है:
\n\n#include <iostream>\n#include <string>\n\ntemplate <typename T>\nT max_value(T a, T b) {\n return (a > b) ? a : b;\n}\n\nint main() {\n std::cout << max_value(10, 20) << std::endl; // 20\n std::cout << max_value(3.14, 2.71) << std::endl; // 3.14\n std::cout << max_value(std::string("apple"), \n std::string("banana")) << std::endl; // banana\n return 0;\n}\n\nकीवर्ड template कंपाइलर को बताता है कि यह एक टेम्पलेट है। <typename T> टेम्पलेट पैरामीटर की सूची है। T प्रकार का एक सशर्त नाम है जिसे बाद में प्रतिस्थापित किया जाएगा। typename के बजाय class का उपयोग किया जा सकता है — इसमें कोई अंतर नहीं है:
template <class T>\nT max_value(T a, T b) {\n return (a > b) ? a : b;\n}\n\nजब आप max_value(10, 20) कॉल करते हैं, तो कंपाइलर देखता है कि तर्क int हैं, और स्वचालित रूप से int के लिए फ़ंक्शन का एक संस्करण बनाता है। इस प्रक्रिया को प्रकार अनुमान कहा जाता है। यदि आवश्यक हो, तो आप स्पष्ट रूप से प्रकार निर्दिष्ट कर सकते हैं:
std::cout << max_value<double>(5, 7.5) << std::endl; // 7.5\n\nमहत्वपूर्ण: टेम्पलेट फ़ंक्शन को हेडर फ़ाइल में (या इसके उपयोग से पहले) परिभाषित किया जाना चाहिए, क्योंकि कंपाइलर को इंस्टेंशिएशन के लिए पूर्ण परिभाषा देखने की आवश्यकता होती है।
\n\nक्लास टेम्पलेट: सार्वभौमिक कंटेनर बनाना
\n\nक्लास टेम्पलेट और भी अधिक शक्तिशाली उपकरण हैं। सबसे उज्ज्वल उदाहरण मानक पुस्तकालय (STL) के कंटेनर हैं: std::vector<int>, st