2016 के प्रबुद्ध युग में, हमारे बेल्ट के नीचे दो नए मानकों के साथ जब से यह सवाल पूछा गया था और कोने के चारों ओर एक नया था, यह जानने के लिए महत्वपूर्ण बात यह है कि C ++ 17 मानक का समर्थन करने वाले कंपाइलर आपके कोड को इस प्रकार संकलित करेंगे ।
C ++ 17 में वर्ग टेम्पलेट के लिए टेम्पलेट-तर्क कटौती
यहाँ (स्वीकार किए गए उत्तर के ओल्झास ज़ुमबेक द्वारा एक संपादन के सौजन्य से) मानक में प्रासंगिक परिवर्तनों का विवरण देने वाला कागज़ है।
अन्य उत्तरों से चिंताओं को संबोधित करना
वर्तमान टॉप-रेटेड उत्तर
यह उत्तर बताता है कि "प्रतिलिपि निर्माता और operator=
" सही टेम्पलेट विशेषज्ञताओं को नहीं जान पाएंगे।
यह बकवास है, क्योंकि मानक कॉपी-कंस्ट्रक्टर और operator=
केवल एक ज्ञात टेम्पलेट प्रकार के लिए मौजूद है :
template <typename T>
class MyClass {
MyClass(const MyClass&) =default;
... etc...
};
// usage example modified from the answer
MyClass m(string("blah blah blah"));
MyClass *pm; // WHAT IS THIS?
*pm = m;
यहाँ, के रूप में मैं टिप्पणी में बताया गया है, है कोई कारण नहीं के लिए MyClass *pm
के साथ या अनुमान के नए रूप के बिना एक कानूनी घोषणा-पत्र होने के लिए: MyClass
एक प्रकार की नहीं है (यह एक टेम्पलेट है), तो यह मतलब नहीं है की एक सूचक की घोषणा करने के टाइप करें MyClass
। उदाहरण को ठीक करने का एक संभावित तरीका यहां दिया गया है:
MyClass m(string("blah blah blah"));
decltype(m) *pm; // uses type inference!
*pm = m;
यहाँ, pm
है पहले से ही सही प्रकार की है, और इसलिए निष्कर्ष तुच्छ है। इसके अलावा, कॉपी-कंस्ट्रक्टर को कॉल करते समय गलती से मिक्स टाइप करना असंभव है :
MyClass m(string("blah blah blah"));
auto pm = &(MyClass(m));
यहाँ, pm
की प्रतिलिपि करने के लिए एक सूचक होगा m
। यहाँ, MyClass
का निर्माण किया जा रहा है , m
जो कि प्रकार का है MyClass<string>
(और कोई नहीं के प्रकार के MyClass
)। इस प्रकार, उस बिंदु पर जहां pm
प्रकार का अनुमान लगाया गया है, यह जानने के लिए पर्याप्त जानकारी है कि टेम्पलेट-प्रकार m
, और इसलिए टेम्पलेट-प्रकार pm
, है string
।
इसके अलावा, निम्नलिखित हमेशा एक संकलन त्रुटि उठाएगा :
MyClass s(string("blah blah blah"));
MyClass i(3);
i = s;
इसका कारण यह है कि कॉपी कंस्ट्रक्टर की घोषणा को समाप्त नहीं किया गया है:
MyClass(const MyClass&);
यहां, कॉपी-कंस्ट्रक्टर तर्क के टेम्प्लेट-प्रकार समग्र रूप से वर्ग के टेम्पलेट-प्रकार से मेल खाते हैं ; यानी, जब MyClass<string>
instantiated है, MyClass<string>::MyClass(const MyClass<string>&);
इसके साथ instantiated है, और जब MyClass<int>
instantiated है, MyClass<int>::MyClass(const MyClass<int>&);
instantiated है। जब तक यह स्पष्ट रूप से निर्दिष्ट नहीं किया जाता है या एक अस्थायी निर्माणकर्ता घोषित किया जाता है, तब तक संकलक के लिए कोई कारण नहीं MyClass<int>::MyClass(const MyClass<string>&);
होता है, जो स्पष्ट रूप से अनुचित होगा।
इसका जवाब Cătălin Pitit ने दिया है
Piti P एक उदाहरण प्रस्तुत करता है Variable<int>
और Variable<double>
फिर कहता है:
मेरे पास दो अलग-अलग प्रकारों (Variable and Variable) के लिए कोड में एक ही प्रकार का नाम (Variable) है। मेरे व्यक्तिपरक दृष्टिकोण से, यह कोड की पठनीयता को काफी प्रभावित करता है।
जैसा कि पिछले उदाहरण में उल्लेख किया गया है, Variable
अपने आप में एक प्रकार का नाम नहीं है, भले ही नई विशेषता यह एक वाक्यात्मक रूप से दिखती है।
Piti तो पूछता है कि अगर कोई कंस्ट्रक्टर नहीं दिया जाता है तो क्या होगा जो उचित अनुमान लगाने की अनुमति देगा। इसका उत्तर यह है कि किसी भी प्रकार के इंजेक्शन की अनुमति नहीं है, क्योंकि निर्माणकर्ता द्वारा कॉल करने पर ट्रिगर चालू हो जाता है । बिना कंस्ट्रक्टर-कॉल के, कोई निष्कर्ष नहीं है ।
यह पूछने के लिए समान है कि यहाँ किस संस्करण foo
को घटाया गया है:
template <typename T> foo();
foo();
उत्तर यह है कि यह कोड अवैध है, कारण बताया गया है।
MSalter का जवाब
यह है, जहां तक मैं बता सकता हूं, प्रस्तावित सुविधा के बारे में एक वैध चिंता लाने का एकमात्र उत्तर है।
उदाहरण है:
Variable var(num); // If equivalent to Variable<int> var(num),
Variable var2(var); // Variable<int> or Variable<Variable<int>> ?
अहम सवाल यह है कि क्या कंपाइलर यहां -टाइप कंस्ट्रक्टर का चयन करता है या कॉपी कंस्ट्रक्टर का?
कोड को आज़माकर, हम देख सकते हैं कि कॉपी कंस्ट्रक्टर का चयन किया गया है। उदाहरण पर विस्तार करने के लिए :
Variable var(num); // infering ctor
Variable var2(var); // copy ctor
Variable var3(move(var)); // move ctor
// Variable var4(Variable(num)); // compiler error
मुझे यकीन नहीं है कि प्रस्ताव और मानक का नया संस्करण यह कैसे निर्दिष्ट करता है; यह "डिडक्शन गाइड्स" द्वारा निर्धारित किया गया प्रतीत होता है, जो एक नया मानक है जो मुझे अभी तक समझ में नहीं आया है।
मुझे यह भी सुनिश्चित नहीं है कि var4
कटौती अवैध क्यों है; जी ++ से संकलक त्रुटि इंगित करती है कि कथन को फ़ंक्शन की घोषणा के रूप में पार्स किया जा रहा है।