2012-12-03 8 views
5

मैंने देखा है कि अद्वितीय टेम्पलेट फ़ंक्शंस को अलग करने के लिए उपयोग किए गए हस्ताक्षर के बीच असमानता है, और अद्वितीय कार्यों को अलग करने के लिए उपयोग किए गए हस्ताक्षर (टेम्पलेट फ़ंक्शंस से तत्काल सहित)।फ़ंक्शन टेम्पलेट्स को असंबद्ध कैसे करें जो केवल रिटर्न प्रकार से भिन्न होते हैं?

विशेष रूप से, टेम्पलेट फ़ंक्शंस जो केवल रिटर्न प्रकार से अलग होते हैं उन्हें अद्वितीय माना जाता है, जबकि फ़ंक्शन जो केवल रिटर्न प्रकार से अलग होते हैं उन्हें अनावश्यक माना जाता है।

#include <iostream> 

template<typename T> 
long foo(T) 
{ 
    std::cout << "long" << std::endl; 
    return 0; 
} 

template<typename T> 
char foo(T) 
{ 
    std::cout << "char" << std::endl; 
    return '\0'; 
} 

int main() 
{ 
    double d = 0.0; 
    long n = foo(d); // <- Ambiguous: How to specify the template function to use? 
} 

उपरोक्त कोड में, टेम्पलेट समारोह foo की इन्स्टेन्शियशन:

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

मैं सैद्धांतिक सीखने के उद्देश्यों के लिए पूरी तरह से यह प्रश्न पूछ रहा हूं। शायद वास्तविक कोड में, यह कोड निर्माण, खराब डिजाइन का संकेत होगा। शायद यह वास्तविक जीवन में कभी नहीं उभरा होगा। साथ ही, मैं टेम्पलेट परिभाषाओं को बदलकर (या अन्य परिवर्तन करके) इस मुद्दे पर काबू पाने के विभिन्न तरीकों की कल्पना कर सकता हूं।

हालांकि, मैं यह जानना चाहूंगा कि, टेम्पलेट परिभाषाओं को अपरिवर्तित रखते हुए, तत्कालता के बिंदु पर इन दो टेम्पलेट कार्यों के बीच असंबद्ध होना संभव है।

उत्तर

6

टेम्पलेट्स का उपयोग करते समय आप वास्तव में दो अलग ओवरलोड को असंबद्ध कर सकते हैं। यह बहुत नहीं है, लेकिन काम करता है:

long n = static_cast<long(*)(double)>(&foo)(d); 
+1

+1 , इस बारे में कभी सोचा नहीं। बदसूरत लेकिन सही है। बीटीडब्ल्यू, 'static_cast <लंबा (&) (डबल)> (foo) (डी)' 1 अक्षर कम करता है :) – iammilind

+0

बिल्कुल सही। अब फंक्शन टेम्पलेट्स में मेरा विश्वास बहाल किया गया है। मैं आश्चर्यचकित होना शुरू कर रहा था कि फ़ंक्शन टेम्पलेट हस्ताक्षर में वापसी प्रकार शामिल नहीं है - अगर उन्हें कभी भी असंबद्ध नहीं किया जा सकता है। लेकिन, जैसा कि आपके उत्कृष्ट उत्तर से पता चलता है, वे कर सकते हैं। –

1

तुम सच में एक ही नाम, मानकों की एक ही सूची है, लेकिन विभिन्न वापसी प्रकार होने दो समारोह टेम्पलेट्स की आवश्यकता है, तो आप कोई विकल्प नहीं है लेकिन बनाकर दो अंतर ,

template <typename R, typename T> 
R foo(T); 

IIRC वहाँ है सी ++ 11 में आंशिक समारोह टेम्पलेट विशेषज्ञता हालांकि मैं मानक में इसके बारे में कुछ भी नहीं मिला: वापसी टेम्पलेट पैरामीटर टाइप करें। अगर वहाँ है, यह काम करना चाहिए:

//partial function template specializations: C++11 only! 
template <typename T> 
long foo<long, T>(T) 
{ 
    std::cout << "long" << std::endl; 
    return 0; 
} 

template<typename T> 
char foo<char, T>(T) 
{ 
    std::cout << "char" << std::endl; 
    return '\0'; 
} 

वरना, सी ++ 03 में:

template <typename R, typename T> 
struct FooImpl; 

template <typename T> 
struct FooImpl<long, T> 
{ 
    static long doIt(T) 
    { 
    std::cout << "long" << std::endl; 
    return 0; 
    } 
}; 

template <typename T> 
struct FooImpl<char, T> 
{ 
    static char doIt(T) 
    { 
    std::cout << "char" << std::endl; 
    return '\0'; 
    } 
}; 

template <typename R, typename T> 
R foo(T t) 
{ 
    return FooImpl<R, T>::doIt(t); 
} 

दोनों ही मामलों में, अपने मुख्य इस प्रकार दिखाई देगा:

int main() 
{ 
    double d = 0.0; 
    long n = foo<long>(d); // specify the return type only 
    auto c = foo<char>(n); 
} 
संबंधित मुद्दे

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