विषय पर बढ़ें

अंतिम अद्यतन:2026-10-12

C++17 क्लास टेम्प्लेट आर्ग्युमेंट डिडक्शन CTAD

आरंभ

C++ टेम्प्लेट मेटाप्रोग्रामिंग हमेशा से C++ डेवलपर्स की एक जानी-मानी क्षमता रही है, चाहे नए सीखने वाले हों या उन्नत डेवलपर, सभी इसकी मदद से प्रकार पैरामीटर वाला सामान्य कोड लिख सकते हैं। C++17 में पेश हुई क्लास टेम्प्लेट आर्ग्युमेंट डिडक्शन (CTAD) के साथ, क्लास टेम्प्लेट से निपटना और भी सहज और लचीला हो गया है।

इस सेक्शन का सारा कोड भी 星球 में अपडेट किया जाएगा।

C++17 द्वारा पेश CTAD इस तरह के फ़ायदे देता है:

उदाहरण के लिए: इतना जटिल कोड

std::vector<FooBar<int, const char*>> obj{a, b, c}; 

हमें केवल इतना चाहिए:

 std::vector obj{a, b, c};

एक और उदाहरण:

std::tuple<int>

इसे सरल बनाया जा सकता है:

std::tuple t1{1};

तो, आज हम CTAD देखते हैं।

CTAD का पूरा नाम Class template argument deduction (CTAD) है, यानी क्लास टेम्प्लेट पैरामीटर डिडक्शन, आप कंपाइलर को एक deduction guide देते हैं, और हम इस विशेषता का उपयोग कर सकते हैं।

यदि न दिया जाए, तो नीचे के उदाहरण की तरह:

#include <iostream>
template <typename T, typename U>
struct MyPair {
  T first{};
  U second{};
};

int main() {
  MyPair<int, int> p1{1, 2};
  MyPair p2{1, 2};
  std::cout << p1.first << ", " << p1.second << std::endl;
  std::cout << p2.first << ", " << p2.second << std::endl;
  return 0;
}

p2 के लिए, हमें यह त्रुटि मिलेगी:

no viable constructor or deduction guide for deduction of template arguments of 'MyPair'

तो इसे कैसे ठीक करें?

केवल deduction guide जोड़ना होगा, नीचे की तरह लिखें।

template <typename T, typename U>
MyPair(T, U) -> MyPair<T, U>;

क्लास टेम्प्लेट आर्ग्युमेंट डिडक्शन (CTAD) कंस्ट्रक्टर पैरामीटर से टेम्प्लेट पैरामीटर का अनुमान लगाने की अनुमति देकर, क्लास टेम्प्लेट के इंस्टेंशिएशन को सरल बनाता है। CTAD से पहले, डेवलपर्स को इंस्टेंशिएट करते समय टेम्प्लेट पैरामीटर स्पष्ट रूप से बताने पड़ते थे। हालांकि, CTAD के ज़रिए यह स्पष्ट निर्देशन अनावश्यक हो जाता है, जिससे कोड पढ़ने और रखरखाव में आसानी होती है।

template <typename T>
class Add{
    private:
        T first;
        T second;
    public:
        Add() = default;
        Add(T first, T second): first_{first}, second_{second} {}
        T result() const { return first + second; }
};

int main(){
    Add one(1,2);               // T被推导为int
    Add two{1.245, 3.1415};     // T被推导为double
    Add three = {0.24f, 0.34f}; // T被推导为float
}

उपरोक्त उदाहरणों में, CTAD प्रकार T को कंस्ट्रक्टर पैरामीटर के आधार पर अनुमानित करने की अनुमति देता है, जिससे स्पष्ट प्रकार निर्देशन की ज़रूरत मिट जाती है।

नॉन-स्टैटिक मेंबर आरंभीकरण

लेकिन एक परिदृश्य है जहाँ CTAD उपयोग नहीं हो सकता, वह है नॉन-स्टैटिक मेंबर आरंभीकरण। उदाहरण के लिए: Test क्लास में बाहर के MyPair का उपयोग करने के लिए पूरा लिखना ही होगा।

template <typename T = int, typename U = int>
struct MyPair {
  T first{};
  U second{};
};

template <typename T, typename U>
MyPair(T, U) -> MyPair<T, U>;

class Test {
  MyPair p4;   // use of class template 'MyPair' requires template arguments; argument
               // deduction not allowed in non-static class member
};

उपरोक्त उदाहरण में, हमने एक टेम्प्लेट क्लास MyPair परिभाषित की और उसमें CTAD का उपयोग किया। हालांकि, जब हम क्लास Test में MyPair को नॉन-स्टैटिक मेंबर की तरह उपयोग करने का प्रयास करते हैं, तो नॉन-स्टैटिक मेंबर आरंभीकरण के संदर्भ के कारण CTAD सामान्य रूप से काम नहीं कर पाता, जिससे compile त्रुटि होती है। ऐसी स्थिति में, हमें MyPair के टेम्प्लेट पैरामीटर स्पष्ट रूप से बताने होंगे।

हम देख सकते हैं कि नॉन-स्टैटिक मेंबर आरंभीकरण के संदर्भ में, CTAD टेम्प्लेट पैरामीटर का अनुमान नहीं लगा पाता। इसलिए, क्लास टेम्प्लेट के नॉन-स्टैटिक मेंबर के रूप में उपयोग हेतु, डेवलपर को सभी टेम्प्लेट पैरामीटर स्पष्ट रूप से बताने होंगे। इस बात पर व्यवहार में विशेष ध्यान देना चाहिए, ताकि कोड की शुद्धता और रखरखाव सुनिश्चित रहे।

संबंधित विषय

टिप्पणियाँ