2016-12-03 9 views
36

सी ++ 17 "टेम्पलेट कटौती गाइड" पेश करता है। मैं इकट्ठा करता हूं कि वे मानक के इस संस्करण में पेश किए गए रचनाकारों के लिए नए टेम्पलेट कटौती के साथ कुछ करने के लिए हैं, लेकिन मैंने अभी तक एक सरल, एफएक्यू-स्टाइल स्पष्टीकरण नहीं देखा है कि वे क्या हैं और वे क्या हैं।टेम्पलेट कटौती मार्गदर्शिकाएं क्या हैं और हमें उनका उपयोग कब करना चाहिए?

  • सी ++ 17 में टेम्पलेट कटौती मार्गदर्शिकाएं क्या हैं?

  • क्यों (और कब) हमें उनकी आवश्यकता है?

  • मैं उन्हें कैसे घोषित करूं?

+3

http://en.cppreference.com/w/cpp/language/class_template_deduction – doug

+0

विशेष रूप से, मुझे यह जानने में दिलचस्पी होगी कि क्या कोई कटौती मार्गदर्शिका वास्तव में सी ++ 17 एसटीएल द्वारा प्रदान की जाती है (उदाहरण के लिए std: : जोड़ी या std :: tuple)। सी ++ 17 के रूप में "deducible" मानक टेम्पलेट प्रकारों की पूरी सूची क्या है? – Quuxplusone

+0

@Quuxplusone http://en.cppreference.com/w/cpp/utility/pair/deduction_guides और http: //en.cppreference।com/w/cpp/utility/tuple/deduction_guides – Cubbi

उत्तर

46

खाका कटौती गाइड एक टेम्पलेट वर्ग है कि कैसे टेम्पलेट तर्क में पैरामीटर का एक सेट (और उनके प्रकार) अनुवाद करने के लिए संकलक बता के साथ संबद्ध पैटर्न हैं।

सबसे आसान उदाहरण std::vector और उसके कन्स्ट्रक्टर है जो एक इटरेटर जोड़ी लेता है।

template<typename Iterator> 
void func(Iterator first, Iterator last) 
{ 
    vector v(first, last); 
} 

संकलक यह पता लगाने की क्या vector<T> के T प्रकार हो जाएगा की जरूरत है। हम जानते हैं कि जवाब क्या है; Ttypename std::iterator_traits<Iterator>::value_type होना चाहिए। लेकिन टाइप करने के लिए के बिना हम संकलक कैसे बता सकते हैं?

template<typename Iterator> vector(Iterator b, Iterator e) -> 
    vector<typename std::iterator_traits<Iterator>::value_type>; 

इस संकलक कि, जब आप उस पैटर्न मिलान एक vector निर्माता कहते हैं, यह -> के दाईं तरफ कोड का उपयोग कर vector विशेषज्ञता निकालना होगा बताता है:

आप एक कटौती गाइड का उपयोग करें।

तर्कों से प्रकार की कटौती उन तर्कों में से किसी एक के प्रकार पर आधारित नहीं होने पर आपको गाइड की आवश्यकता होती है। से vector को प्रारंभ में vector के T का स्पष्ट रूप से उपयोग करता है, इसलिए इसे मार्गदर्शिका की आवश्यकता नहीं है।

बाईं ओर एक कन्स्ट्रक्टर निर्दिष्ट नहीं करता है। जिस तरह से यह काम करता है वह यह है कि, यदि आप किसी प्रकार पर टेम्पलेट कन्स्ट्रक्टर कटौती का उपयोग करते हैं, तो यह उन सभी तर्कों से मेल खाता है जो आप सभी कटौती मार्गदर्शिकाओं के खिलाफ पार करते हैं (वास्तविक रचनाकार निहित मार्गदर्शिकाएं प्रदान करते हैं)। यदि कोई मिलान होता है, तो यह उस प्रकार के टेम्पलेट तर्कों को निर्धारित करने के लिए उपयोग करता है। लेकिन उस के बाद कॉल करने के लिए कौन सा कन्स्ट्रक्टर होता है यह निर्धारित करने के लिए ओवरलोड रिज़ॉल्यूशन।

यह भी मतलब है कि आप समुच्चय और कुल आरंभीकरण के साथ गाइड का उपयोग कर सकते हैं:

template<typename T> 
struct Thingy 
{ 
    T t; 
}; 

Thingy(const char *) -> Thingy<std::string>; 

Thingy thing{"A String"}; //thing.t is a `std::string`. 

तो कटौती गाइड ही प्रकार यह पता लगाने के लिए किया जाता प्रारंभ किया जा रहा। प्रारंभिकरण की वास्तविक प्रक्रिया ठीक उसी तरह काम करती है जैसा कि पहले किया गया था, एक बार यह दृढ़ संकल्प किया गया था।

+3

हम्म, यह सिर्फ मेरे लिए हुआ कि गाइड के साथ भी, 'वेक्टर वी {पहला, अंतिम};' सही काम नहीं करेगा :( –

+6

@TC: यह " आपके लिए समान प्रारंभिकरण " –

+0

@TC ... जब तक कि सही चीज इटरेटर के वेक्टर नहीं बना रही हो। और' std :: string {32, '*'} [0] == '' '' (ASCII के लिए)। लेकिन सी ++ 11 के बाद यह सब सच रहा है। –

संबंधित मुद्दे