2013-05-31 6 views
10

मेरे आश्चर्य करने के लिए इस कार्यक्रम के दोनों MSCV और जीसीसी में संकलित एक ही:विधि नाम के रूप में सी में टेम्पलेट विधि नाम ++

class A 
{ 
public: 
    int add() { return 0; } 
    template<typename T> 
    T add() { return T(); } 
}; 

int main() { 
    A a; 
    a.add(); 
    a.add<int>(); 
    return 0; 
} 

जाहिर है, तथ्य यह है कि टेम्प्लेटेड विधि के प्रकार नहीं निष्कर्ष निकाला जा सकता है और करने की जरूरत है की वजह से स्पष्ट रूप से कहा जाना चाहिए, इसलिए स्थिति महत्वाकांक्षी नहीं है - फिर भी यह थोड़ा सा छायादार लगता है - अगर यह एक गैर-टेम्पलेट विधि थी जो स्पष्ट रूप से गलत होगी।

मैंने googling और मानक के अंतिम मसौदे को देखने की कोशिश की है, लेकिन जवाब नहीं मिला - एक टेम्पलेट विधि का एक समान नामकरण और एक सामान्य विधि है जो सी ++ में वापसी प्रकार कानूनी रूप से भिन्न होती है, या संकलक सिर्फ अनुमोदित जा रहे हैं?

उत्तर

10

यह हमेशा कानूनी सी ++ रहा है।

14.5.6/2:

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

add<int> की तरह "टेम्पलेट-आईडी" सिंटैक्स का उपयोग करते हैं, पर्याप्त टेम्पलेट मानकों के साथ ही टेम्पलेट कार्यों माना जाता है। तो a.add<int>() यह भी नहीं देखता कि गैर-टेम्पलेट add मैचों।

जब कोई पहचानकर्ता सादा फ़ंक्शन और फ़ंक्शन टेम्पलेट दोनों नाम देता है, तो संकलक टेम्पलेट फ़ंक्शन विशेषज्ञता प्राप्त करने के लिए फ़ंक्शन टेम्पलेट के लिए टेम्पलेट तर्कों को कम करने का प्रयास करेगा। फिर सभी सादा कार्य और सभी टेम्पलेट फ़ंक्शन विशेषज्ञता सामान्य फ़ंक्शन अधिभार तर्क से तुलना की जाती हैं। [13.3.1/7 देखें।]

आपके उदाहरण में, कॉल a.add() टेम्पलेट संस्करण T टेम्पलेट संस्करण के लिए कम नहीं कर सकता है। तो एकमात्र व्यावहारिक कार्य गैर-टेम्पलेट अधिभार है।

एक और नियम भी है जो एक समान स्थिति में आता है: यदि एक गैर-टेम्पलेट फ़ंक्शन और टेम्पलेट फ़ंक्शन विशेषज्ञता अन्यथा एक संदिग्ध ओवरलोड हो, तो गैर-टेम्पलेट फ़ंक्शन जीतता है। [यह नियम क्या एक समारोह तर्क का एक सेट के लिए एक और की तुलना में बेहतर बनाता है की परिभाषा के बीच में खंड 13.3.3 में है।]

class B 
{ 
public: 
    int f(int n) { return n+1; } 

    template<typename T> 
    T f(T n) { return n; } 
}; 

int main() { 
    B b; 
    b.f(1);  // both are viable, non-template wins 
    b.f<int>(1); // only the template is viable 
    return 0; 
} 

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

+0

वाह, उत्तरार्द्ध और भी दिलचस्प है - इसे ध्यान में रखेगा, धन्यवाद! –

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