2012-02-08 10 views
13

मैं कोण कोष्ठक के लिए इस्तेमाल किया कर रहा हूँ एक पैरामीटर के रूप में, एक प्रकार का उल्लेख करने के लिए इस्तेमाल किया जा रहातर्क मानों के लिए कोण ब्रैकेट क्या है, और इसका उपयोग किस लिए किया जाता है?</p> <pre><code>vector<int> vecOfInts ; </code></pre> <p>लेकिन <a href="http://code.google.com/p/rapidjson/">rapidjson</a> में, वहाँ इस तरह कोड है::

document.Parse<0>(json) ; 

document.Parse विधि के हस्ताक्षर है:

template <unsigned parseFlags> 
GenericDocument& Parse(const Ch* str) { 
    RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); 
    GenericStringStream<Encoding> s(str); 
    return ParseStream<parseFlags>(s); 
} 

मुझे नहीं पता था कि आप मान पास कर सकते हैं साइड कोण ब्रैकेट्स - सोचा कोण कोण ब्रैकेट का उपयोग अकेले टाइपनाम के लिए किया जाता था।

यहां कोड क्या है, और वह कोण ब्रैकेट में मान क्यों गुजर रहा है?

क्या यह एक अच्छा विचार है? कब?

+0

संभावित डुप्लिकेट [नियमित पैरामीटर के बजाय गैर-प्रकार टेम्पलेट पैरामीटर का उपयोग करने का कारण?] (Http://stackoverflow.com/questions/7395700/reason-for-using-non-type-template-parameter-instead- ऑफ-नियमित-पैरामीटर) –

+2

"गैर-प्रकार का टेम्पलेट पैरामीटर" देखें। –

उत्तर

18

यहां दो अलग-अलग कारक चल रहे हैं।

सबसे पहले, उन टेम्पलेट्स को परिभाषित करना संभव है जो कि प्रकारों के अलावा अन्य चीज़ों पर पैरामीटरकृत हैं।

template <typename T, size_t N> struct Array { 
    T arr[N]; 
}; 

हम जैसे

Array<int, 137> myArray; 

हम जानते हैं कि vector<int> और vector<double> विभिन्न प्रकार हैं इस का उपयोग कर सकते हैं: उदाहरण के लिए, यहाँ एक सरल सरणी प्रकार है। लेकिन अब हमें यह भी इंगित करना होगा कि Array<int,137> और Array<int,136> विभिन्न प्रकार हैं।

दूसरा, टेम्पलेट का उपयोग करते समय, कंपाइलर को सभी टेम्पलेट तर्कों के लिए एक मूल्य का पता लगाने में सक्षम होना चाहिए। जब आप टेम्पलेट कक्षाओं का उपयोग कर रहे हैं, तो यही कारण है कि आप आमतौर पर सभी टेम्पलेट तर्क निर्दिष्ट करते हैं। उदाहरण के लिए, आप vector x नहीं कहें, बल्कि इसके बजाय vector<double> x जैसे कुछ कहें। टेम्पलेट फ़ंक्शंस का उपयोग करते समय, अधिकांश समय संकलक तर्कों को समझ सकते हैं। उदाहरण के लिए, std::sort उपयोग करने के लिए, तो आप सिर्फ

std::sort(v.begin(), v.end()); 

की तरह कुछ लेकिन, आप भी लिख सकता है

std::sort<vector<int>::iterator>(v.begin(), v.end()); 

अधिक स्पष्ट होने के लिए कहते हैं। लेकिन कभी-कभी, आपके पास एक टेम्पलेट फ़ंक्शन होता है जिसके लिए सभी तर्कों का पता नहीं लगाया जा सकता है।

template <unsigned parseFlags> 
GenericDocument& Parse(const Ch* str) { 
    RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); 
    GenericStringStream<Encoding> s(str); 
    return ParseStream<parseFlags>(s); 
} 

सूचना है कि parseFlags टेम्पलेट पैरामीटर सिर्फ समारोह के तर्कों से निष्कर्ष निकाला नहीं जा सकता है: अपने उदाहरण में, हम इस किया है। नतीजतन, फ़ंक्शन को कॉल करने के लिए, आप टेम्पलेट पैरामीटर निर्दिष्ट करें, अन्यथा संकलक इसे समझ नहीं सकता है। यही कारण है कि आप

Parse<0>(myString); 

यहाँ की तरह कुछ क्यों लिख करेंगे, 0 एक टेम्पलेट तर्क (संकलन समय पर हल हो गई), और myString वास्तविक तर्क (रन-टाइम में हल हो गई है)।

आप वास्तव में ऐसे विधियां कर सकते हैं जो थोड़ा प्रकार के अनुमान और थोड़ा स्पष्ट प्रकार पैरामीटर को जोड़ते हैं। उदाहरण के लिए, बूस्ट में, lexical_cast फ़ंक्शन है जो स्ट्रिंग प्रकारों से और उससे रूपांतरण कर सकता है। समारोह हस्ताक्षर एक स्ट्रिंग प्रकार के लिए एक गैर-स्ट्रिंग प्रकार से परिवर्तित करने के लिए यहां

template <typename Target, typename Source> 
    Target lexical_cast(const Source& arg); 

है, यदि आप lexical_cast फोन, संकलक पता लगा सकते हैं क्या Source है, लेकिन यह कुछ संकेत के बिना Target अनुमान नहीं कर सकते। lexical_cast उपयोग करने के लिए है, इसलिए, आप की तरह

std::string myString = boost::lexical_cast<std::string>(toConvertToString); 

कुछ अधिक आम तौर पर लिखना चाहते हैं, संकलक कहते हैं आप टेम्पलेट तर्क (वैकल्पिक 0) के कुछ संख्या निर्दिष्ट करने के लिए है, और यह बाकी अनुमान करने की कोशिश करेंगे कि। अगर यह कर सकता है, तो बढ़िया! यदि नहीं, तो यह संकलन-समय त्रुटि है। इस का उपयोग करना, यदि आप चाहें, तो आप

template <int IntArgument, typename TypeArgment> 
    void DoSomething(const TypeArgument& t) { 
     /* ... */ 
} 

की तरह एक समारोह लिख सकता है इस फ़ंक्शन को कॉल करने के लिए, अगर आप इस तरह यह आह्वान करने के लिए होगा:

DoSomething<intArg>(otherArg); 

यहाँ, इस वजह से आप काम करता है IntArgument क्या संकलक स्पष्ट रूप से बताना है, लेकिन फिर संकलक को DoSomething पर तर्क के प्रकार से घटा सकता है।

आशा है कि इससे मदद मिलती है!

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