c++ - स्ट्रिंग शाब्दिक अंतराल और रेवल्यू संदर्भ के लिए फ़ंक्शन अधिभार




language-lawyer overload-resolution (2)

  1. कौन सा कंपाइलर सही है?

जीसीसी सही है।

  1. क्लैंग के साथ, क्यों str1 और str2, जब वे अंतराल होते हैं, तो ओवरलोड का चयन करते हैं?

क्लैंग test(str1); पर गलत है test(str1); , यह अस्पष्ट होना चाहिए। test(str2); , str2 सूचक को str2 बदल सकता है, अर्थात् सरणी-से-सूचक क्षय। परिवर्तित char* एक लकीर है। # 3 के समान कारण के लिए, अंतर्निहित रूपांतरण अनुक्रमों की रैंकिंग समान है, फिर गैर-टेम्पलेट फ़ंक्शन को प्राथमिकता दी जाती है; test(char*&&) चुना गया है।

  1. जीसीसी के साथ, str1 के साथ कॉल अस्पष्ट क्यों है?

test(const char (&)[1]) को बुलाया जाएगा, char[1] से char[1] तक योग्यता रूपांतरण आवश्यक है; test(char*&&) बुलाया जाना चाहिए, सरणी-से-सूचक रूपांतरण आवश्यक है। दोनों सटीक मैच के रूप में योग्य हैं और समान रैंकिंग वाले हैं।

  1. क्या इस स्थिति के लिए एक मानक नियम है?

अधिभार संकल्प , और निहित रूपांतरणों में निहित रूपांतरण अनुक्रमों की रैंकिंग देखें।

  1. दो आखिरी कॉल को कैसे ठीक करें?

यह आपके इरादे पर निर्भर करता है।

नीचे दिए गए फंक्शन test को लोवल्यू खाली स्ट्रिंग्स, लैवल्यू नॉन-खाली स्ट्रिंग्स और रवेल्यू स्ट्रिंग्स के लिए अतिभारित किया गया है। मैंने क्लैंग और जीसीसी के साथ संकलन करने की कोशिश की, लेकिन दोनों ही मामलों में मेरे पास अपेक्षित परिणाम नहीं है।

#include <iostream>

void test(const char (&)[1]){ std::cout << __PRETTY_FUNCTION__ << std::endl; }

template <unsigned long int N>
void test(const char (&)[N]){ std::cout << __PRETTY_FUNCTION__ << std::endl; }

void test(char*&&){ std::cout << __PRETTY_FUNCTION__ << std::endl; }

int main(){
    char str1[] = "";
    char str2[] = "test";
    test("");
    test("test");
    test(str1);
    test(str2);
}

क्लैंग संस्करण 6.0.0-1ubuntu2 के साथ आउटपुट:

clang++ test.cpp -o test.out && ./test.out
void test(const char (&)[1])
void test(const char (&)[N]) [N = 5]
void test(char *&&)
void test(char *&&)

G ++ के साथ आउटपुट (MINGW.org GCC-8.2.0-3) :

g++ test.cpp -o test.exe && test.exe
test.cpp: In function 'int main()':
test.cpp:15:11: error: call of overloaded 'test(char [1])' is ambiguous
  test(str1);
           ^
test.cpp:3:6: note: candidate: 'void test(const char (&)[1])'
 void test(const char (&)[1]){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
      ^~~~
test.cpp:6:6: note: candidate: 'void test(const char (&)[N]) [with long unsigned int N = 1]'
 void test(const char (&)[N]){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
      ^~~~
test.cpp:8:6: note: candidate: 'void test(char*&&)'
 void test(char*&&){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
      ^~~~

मेरे प्रश्न हैं:

  1. कौन सा कंपाइलर सही है?
  2. test(str2) साथ, test(str1) और test(str2) वे अंतराल क्यों हैं, जबकि वे अंतराल हैं?
  3. GCC के साथ, कॉल test(str1) अस्पष्ट क्यों है?
  4. क्या इस स्थिति के लिए एक मानक नियम है?
  5. दो आखिरी कॉल को कैसे ठीक करें?

धन्यवाद।


आपके उत्तर के लिए धन्यवाद @songyuanyao, मुझे अब समझ में आया कि दो अंतिम मामलों में test(char*&&) क्यों चुना जाता है। मैं पहले अतिभार पर @Darklighter जवाब के लिए टेम्पलेट विशेषज्ञता के साथ अस्पष्टता को दूर करने में सक्षम था।

तो मैंने अपनी समस्या हल की जैसे कि:

#include <iostream>

template <unsigned long int N>
void test(const char (&)[N]){
    std::cout << __PRETTY_FUNCTION__ << " //non-empty literal" << std::endl;
}

template <>
void test(const char (&)[1]){
    std::cout << __PRETTY_FUNCTION__ << " //empty literal" << std::endl;
}

void test(char*&&){
    std::cout << __PRETTY_FUNCTION__ << " //string variable" << std::endl;
}

int main(){
    char str1[] = "";
    char str2[] = "test";
    test("");
    test("test");
    test(str1);
    test(str2);
}

आउटपुट:

clang++ test.cpp -o test.out && ./test.out
void test(const char (&)[1]) //empty literal
void test(const char (&)[N]) [N = 5] //non-empty literal
void test(char *&&) //string variable
void test(char *&&) //string variable

g++ test.cpp -o test.exe && test.exe
void test(const char (&)[N]) [with long unsigned int N = 1] //empty literal
void test(const char (&)[N]) [with long unsigned int N = 5] //non-empty literal
void test(char*&&) //string variable
void test(char*&&) //string variable






value-categories