2012-11-26 16 views
7

मैं कोड के इस टुकड़े भर में आ गए हैं करने के उद्देश्य क्या (मैं सब मैं कुछ याद कर रहा हूँ मामले में विवरण शामिल करने की कोशिश कर रहा हूँ) टी समझ में टेम्पलेट के अंदर कार्य है:टेम्पलेट्स अंदर typename काम

template <typename TYPE = TYPE_with_an_arbitrarily_long_name, .. 

मैं इस के प्रभाव को समझने की कोशिश कर रहा है, लेकिन अब तक मैं किसी भी उत्पादन नहीं कर सका। यहाँ कर रहे हैं कुछ सामान मैं कोशिश की है:

#include <iostream> 
#include <typeinfo> 
using namespace std; 

template<typename T> 
void foo(T t) { 
    cout << typeid(t).name() << " "; 
} 

template<typename T = int> 
void bar(T t) { 
    cout << typeid(t).name() << " "; 
} 

template<typename T = double> 
void baz(T t) { 
    cout << typeid(t).name() << " "; 
} 

int main() 
{ 
    cout << "\nfoo: "; 
    foo(3); foo<int>(3); foo<double>(3); 
    cout << "\nbar: "; 
    bar(3); bar<int>(3); bar<double>(3); 
    cout << "\nbaz: "; 
    baz(3); baz<int>(3); baz<double>(3); 
    return 0; 
} 

प्रिंट आउट:

foo: i i d 
bar: i i d 
baz: i i d 

तो मेरे सवाल है:

  1. template अंदर काम के प्रभाव क्या है?
  2. ऊपर के उदाहरण में इसका उपयोग करने का उद्देश्य क्या है?
  3. कोई तीसरा सवाल ही नहीं है।

.. किसी भी मदद की सराहना की

संपादित निकला कार्यों C++ 11

उत्तर

7

यह 'डिफ़ॉल्ट टेम्पलेट तर्क' और निर्दिष्ट करता है कि किस प्रकार प्रयोग किया जाता है, जब कुछ भी निर्दिष्ट कहा जाता है - एक जैसे डिफ़ॉल्ट फ़ंक्शन पैरामीटर इस तकनीक का व्यापक रूप से कक्षाओं के लिए प्रयोग किया जाता है - std::vector या std::string की परिभाषा को देखो, और आप वे एक से अधिक डिफ़ॉल्ट प्रकार पैरामीटर देखेंगे। समारोह टेम्पलेट्स के लिए डिफ़ॉल्ट प्रकार पैरामीटर के लिए

बेस्ट उपयोग जब प्रकार तर्क आसानी से वास्तविक तर्क से निष्कर्ष निकाला नहीं किया जा सकता है, और यह स्पष्ट रूप से निर्दिष्ट नहीं है - तो संकलक डिफ़ॉल्ट का उपयोग करेगा। आपके उदाहरण में डिफ़ॉल्ट प्रकारों की कोई आवश्यकता नहीं है, क्योंकि इसे वास्तविक कॉल पैरामीटर से आसानी से हटाया जा सकता है।

जब तक सी ++ 0x डिफ़ॉल्ट प्रकार पैरामीटर केवल क्लास टेम्पलेट्स के लिए अनुमति नहीं दी गई थी - फ़ंक्शन टेम्पलेट्स के साथ उपयोग करना संभव नहीं था। सी ++ 0x के साथ यह बदल गया, लेकिन कुछ पुराने कंपाइलर्स (उदाहरण के लिए विज़ुअल सी ++ 2008) आपको उनका उपयोग करने नहीं देंगे।

+1

नाइटपिकिंग: 'std :: string' में कोई टेम्पलेट पैरामीटर नहीं है, क्योंकि यह' typedef' है ('std :: basic_string ') के लिए; आप किस बारे में बात कर रहे हैं शायद 'std :: basic_string' है, जिसमें लक्षण और आवंटक पैरामीटर के लिए डिफ़ॉल्ट मान (वर्ण प्रकार के आधार पर) हैं। –

+0

+1 मुझे एहसास करने के लिए +1 मैं – none

7

के साथ ही compilable ये कार्य बल्कि के प्रकार के तर्क के लिए "डिफ़ॉल्ट मान" नहीं कर रहे हैं टेम्पलेट, जैसे कार्यों के डिफ़ॉल्ट मान तर्कों के लिए एक समान वाक्यविन्यास है। उनका उपयोग तब किया जाता है जब एक स्पष्ट तर्क निर्दिष्ट नहीं किया जाता है।

bar और baz आपके उदाहरण में फ़ंक्शन टेम्पलेट्स के लिए, यह कोई समझ नहीं आता है क्योंकि इन कार्यों के लिए T निर्दिष्ट तर्कों से लिया जाएगा।

+0

मैंने ऐसा सोचा लेकिन 'बाज़ (3) 'रिटर्न' i' क्यों करता है? – none

+2

क्योंकि '3'' int' अक्षर है? –

+0

जैसा कि मैंने कहा था, 'बार' और 'baz' के लिए आपके द्वारा निर्दिष्ट डिफ़ॉल्ट का कभी भी उपयोग नहीं किया जाता है। वे हमेशा वास्तविक पैरामीटर के प्रकार के अनुसार तत्काल होते हैं, इसलिए 'बाज़ (3)' के लिए कॉल का अर्थ वास्तव में 'बाज़ (3) 'है। –

-3

आप के लिए क्या देख रहे हैं "खाका विशेषज्ञता"

यहाँ कुछ Example/Explanation

+0

स्पष्ट टेम्पलेट विशेषज्ञता यहां शामिल नहीं है, वे केवल डिफ़ॉल्ट टेम्पलेट पैरामीटर हैं। –

6

एक समारोह-टेम्पलेट सबसे अच्छा निर्माण डिफ़ॉल्ट टेम्पलेट तर्क प्रदर्शित करने के लिए नहीं हो सकता है के लिए एक लिंक है। यहाँ टेम्पलेट structs के साथ कुछ ऐसा ही है:

#include <iostream> 
#include <typeinfo> 

template<typename T = int> 
struct foo { 
    static void f() { 
     std::cout << typeid(T).name() << "\t"; 
    } 
}; 

template<typename T = double> 
struct bar { 
    static void f() { 
     std::cout << typeid(T).name() << "\t"; 
    } 
}; 

int main() { 
    foo<>::f(); foo<int>::f(); foo<double>::f(); std::cout << std::endl; 
    bar<>::f(); bar<int>::f(); bar<double>::f(); std::cout << std::endl; 
} 

इस चल रहा है, मैं:

% ./a.out 
i i d 
d i d 
+0

तो यह 'स्ट्रक्चर' के लिए काम करता है लेकिन काम नहीं करता है? – none

+0

डिफ़ॉल्ट टेम्पलेट तर्क (हमें) फ़ंक्शन के साथ समझ में नहीं आता है क्योंकि टेम्पलेट-प्रकार फ़ंक्शन-तर्क प्रकार द्वारा निहित है। कक्षाओं और structs के साथ, आपको या तो स्पष्ट रूप से प्रकार को परिभाषित करना होगा, या डिफ़ॉल्ट प्रकार (यदि प्रदान किया गया हो) का उपयोग करना होगा। – eduffy

1

ये डिफ़ॉल्ट टेम्पलेट तर्क हैं। आप उनके उपयोग को सरल बनाने के लिए टेम्पलेट डिफ़ॉल्ट तर्क का उपयोग कर सकते हैं।

जब आपके पास दो टेम्पलेट पैरामीटर हैं, उदाहरण के लिए, और अंतिम को एक डिफ़ॉल्ट प्रकार दें, तो आपको केवल एक ही प्रकार निर्दिष्ट करना होगा।

std::vector, उदाहरण के लिए,

template < class T, class Allocator = allocator<T> > class vector; 

यहाँ आप Allocator के लिए एक डिफ़ॉल्ट टेम्पलेट तर्क है, तो आप सिर्फ एक तर्क के साथ वैक्टर परिभाषित कर सकते हैं के रूप में परिभाषित किया गया है

std::vector<int> v; 
2
  1. "कार्य "टेम्पलेट पैरामीटर सूची के अंदर डिफ़ॉल्ट पैरामीटर हैं, जैसे फ़ंक्शन पैरामीटर सूचियों में। इसका मतलब है कि आपके उदाहरण में, Foo<>Foo<TYPE_with_an_arbitrarily_long_name, KIND_with_an_arbitrarily_long_name> जैसा ही है, और Foo<int>Foo<int, KIND_with_an_arbitrarily_long_name> जैसा ही है।
  2. इसका उपयोग आपके उदाहरणों में नहीं किया जाएगा। आप Foo का उपयोग नहीं करते हैं, और baz और bar के पैरामीटर हमेशा दिए गए तर्कों से संकलक द्वारा घटाए जाएंगे।
+0

पर अपने '-std = C++ 0x' स्विच को भूल गया था (1) फ़ंक्शन उदाहरणों के लिए 'Foo' को ध्यान में रखें, फ़ंक्शन केवल प्रदर्शन के लिए हैं जबकि' Foo 'वास्तविक था कोड मैंने देखा (2) तो जब कभी कुछ निर्दिष्ट नहीं किया जाता है तो जब मैं कुछ निर्दिष्ट नहीं करता और ओवरराइड करता हूं तो 'डिफ़ॉल्ट पैरामीटर' कभी भी उपयोग किए जाते हैं? – none

+0

वे आपके उदाहरण_ में अनुमानित हैं क्योंकि आपके उदाहरण कार्य हैं। चूंकि आपने जंगली में देखा गया कोड वास्तव में वर्ग टेम्पलेट 'फू' था, इसलिए 'फू <>' और 'Foo ' पर विचार करें, जिसे मैंने ऊपर वर्णित किया है। - या @eduffy द्वारा प्रदान किए गए उत्तर को देखें –

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