2016-11-24 9 views
6

के साथ विधि पर आकार टेम्पलेट के साथ विधि को प्राथमिकता देते समय, मुझे लगता है कि एकाधिक मिलान उपलब्ध होने पर संकलक सरल मिलान का चयन करेगा।पॉइंटर प्रकार

#include <iostream> 
#include <string> 

struct A { 
    static void foo(const char *str) { 
     std::cout << "1: " << str << std::endl; 
    } 

    template<int N> static void foo(const char (&str)[N]) { 
     std::cout << "2: " << str << std::endl; 
    } 
}; 

int main() 
{ 
    A::foo("hello"); 
} 

उत्पादन 1: hello है:

इस कोड पर विचार करें। फिर भी, अगर मैं static void foo(const char *str) विधि पर टिप्पणी करता हूं, तो यह ठीक संकलित करता है और 2: hello आउटपुट करता है।

मेरे पास कक्षा में दोनों विधियां कैसे हो सकती हैं जैसे ज्ञात आकार वाले सरणी टेम्पलेट विधि को कॉल करेंगे, और पॉइंटर प्रकार गैर-टेम्पलेट विधि को कॉल करेंगे?

मैंने कोशिश की है:

struct A { 
    template<class _Ty = char> 
    static void foo(const _Ty *str) { 
     std::cout << "1: " << str << std::endl; 
    } 

    template<int N> static void foo(const char (&str)[N]) { 
     std::cout << "2: " << str << std::endl; 
    } 
}; 

लेकिन जी ++ मुझे निम्न त्रुटि देता है:

In function 'int main()': 
17:17: error: call of overloaded 'foo(const char [6])' is ambiguous 
17:17: note: candidates are: 
6:15: note: static void A::foo(const _Ty*) [with _Ty = char] 
10:32: note: static void A::foo(const char (&)[N]) [with int N = 6] 
+3

सबसे पहले, '_Ty' का उपयोग न करें, जो कार्यान्वयन के लिए आरक्षित है। दूसरा, 'कॉन्स टी * कॉन्स एंड स्ट्र'। –

+0

धन्यवाद, यह काम करता है! टी बनाम _Ty के लिए, मैं सम्मान से असहमत हूँ। 'टी' एक भयानक नामकरण विकल्प है जब इसे अपने टेक्स्ट एडिटर में खोजना पड़ता है। – GaspardP

+1

यह "आदरणीय असहमत" का सवाल नहीं है, यह एक सवाल है "किसी भी स्पष्ट कारण के लिए टूटा जा सकता है।" आप कार्यान्वयन आरक्षित टाइपनाम का उपयोग कर रहे हैं। http://stackoverflow.com/questions/12924243/are-identifiers-starting-with-an-underscore-reserved-according-to-the-latest-c – druckermanly

उत्तर

1

द्वारा टीसी सुझाव के रूप में, यह काम करता है:

struct A { 

    template<class T, typename = typename std::enable_if<std::is_same<T, char>::value>::type> 
    static void foo(const T * const & str) { 
     std::cout << "1: " << str << std::endl; 
    } 

    template<int N> static void foo(const char (&str)[N]) { 
     std::cout << "2: " << str << std::endl; 
    } 
}; 

int main() 
{ 
    A::foo("hello1"); 

    const char *c = "hello2"; 
    A::foo(c); 

    char *c2 = new char[7]; 
    ::strcpy(c2, "hello3"); 
    A::foo(c2); 

    // does not compile 
    // int *c3; 
    // A::foo(c3); 
} 

आउटपुट:

2: hello1 
1: hello2 
1: hello3 

मेरी इच्छा है कि मुझे सूचक विधि को टेम्पलेट करने की आवश्यकता नहीं है क्योंकि यह अप्रत्याशित प्रकारों के साथ दुरुपयोग का द्वार खोलता है, लेकिन मैं इस समाधान के साथ रह सकता हूं।

+1

'कॉन्स टी * और स्ट्र 'पर्याप्त है? – Danh

+1

यदि आप अप्रत्याशित प्रकारों के उपयोग के बारे में चिंतित हैं, तो आप 'std :: enable_if' और' std :: is_same' का उपयोग यह सत्यापित करने के लिए कर सकते हैं कि 'टी' प्रकार' char' है, नहीं? – druckermanly

+0

'कॉन्स्ट टी * और स्ट्र 'वास्तव में पर्याप्त – GaspardP

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