2013-05-23 4 views
11

क्या सी ++ 11 में const char* और स्ट्रिंग अक्षर (const char[]) अधिभारित करना संभव है? यह विचार स्ट्रिंग लंबाई खोजने के लिए strlen पर कॉल करने से बचने के लिए है जब यह लंबाई पहले से ज्ञात है।कानूनी रूप से स्ट्रिंग अक्षर और कॉन्स चार * को अधिभारित करना संभव है?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

template<typename T, int N> 
void length(const T(&data)[N]) { 
    printf("%u[]\n", N - 1); 
} 

template<typename T> 
void length(const T* data) { 
    printf("*%u\n", (unsigned)strlen(data)); 
} 

int main() { 
    length("hello"); 
    const char* p = "hello"; 
    length(p); 
    return 0; 
} 

त्रुटि (बजना):

जी ++ 4.8 और बजना ++ 3.2 पर

यह टुकड़ा टूट

test2.cpp:16:3: error: call to 'length' is ambiguous 
    length("hello"); 
    ^~~~~~ 
test2.cpp:6:6: note: candidate function [with T = char, N = 6] 
void length(const T(&data)[N]) { 
    ^
test2.cpp:11:6: note: candidate function [with T = char] 
void length(const T* data) { 
    ^
1 error generated. 

थोड़ा हैक कर लिया गया है, और इस काम करने के लिए प्रकट होता है:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

template<typename T, int N> 
void length(const T(&data)[N]) { 
    printf("%u[]\n", N - 1); 
} 

template<typename T> 
void length(T&& data) { 
    printf("*%u\n", (unsigned)strlen(data)); 
} 

const char *foo() { 
    return "bar"; 
} 

int main() { 
    length("hello"); 
    const char* p = "hello"; 
    length(p); 
    length(foo()); 
    return 0; 
} 

क्या यह मान्य सी ++ 11 है? सरणी विशेषज्ञता हटा दिए जाने पर स्ट्रिंग अक्षर T&& पर ओवरलोड पर प्रतीत होता है। इस अस्पष्टता को हल करने का क्या कारण बनता है, लेकिन पहले कोड स्निपेट में से कोई नहीं?

+1

अजीब, मुझे [अलग व्यवहार] (http://ideone.com/3vrQkG) मिलता है, और यह इस बात पर निर्भर करता है कि 'char' टेम्पलेट तर्क है या नहीं ... –

+0

[यह] (http: // stackoverflow .com/a/11625621/845568) उत्तर में क्या हो रहा है इसके बारे में कुछ प्रासंगिक जानकारी है ... –

+0

@KerrekSB: यह स्पष्ट रूप से असहज है :( –

उत्तर

4

पहले मामले में, ओवरलोड रिज़ॉल्यूशन के दौरान आपके पास एक सटीक मिलान होता है जिसमें एक आइर के खिलाफ पॉइंटर रूपांतरण (जो कि "लवल्यू ट्रांसफॉर्मेशन" श्रेणी में होता है, साथ ही रैवल्यू और पॉइंटर रूपांतरण में फ़ंक्शन के साथ) में कोई रूपांतरण नहीं होता है। एक अंतर जो केवल एक लवली परिवर्तन द्वारा किया जाता है, विजेता चुनने के लिए ओवरलोड रिज़ॉल्यूशन के लिए पर्याप्त नहीं है।

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


आपके अन्य प्रश्न के लिए - नहीं, स्ट्रिंग अक्षर के लिए विशेष रूप से ओवरलोडिंग संभव नहीं है। आप हमेशा उनके साथ एक ही आकार के सरणी पकड़ने जा रहे हैं।

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