निम्न कोड संकलित क्यों नहीं करता है, और जब मैं कक्षा ए में कन्स्ट्रक्टर से पहले स्पष्ट कीवर्ड हटा देता हूं, तो यह संकलित करता है?ओवरलोड रिज़ॉल्यूशन में "स्पष्ट" कन्स्ट्रक्टर का प्रभाव
विजुअल स्टूडियो 2013 का उपयोग करना:
enum E { e1_0, e1_1 };
template<typename T>
struct A
{
A() {}
explicit A(unsigned long) {}
A(T) {}
};
struct B
{
B() {}
B(E) {}
};
void F(B) {};
void F(A<short>) {};
void test()
{
F(e1_0);
}
त्रुटि:
1>------ Build started: Project: exp_construct_test, Configuration: Debug Win32 ------
1> exp_construct_test.cpp
1>e:\exp_construct_test\exp_construct_test.cpp(23): error C2668: 'F' : ambiguous call to overloaded function
1> e:\exp_construct_test\exp_construct_test.cpp(19): could be 'void F(A<short>)'
1> e:\exp_construct_test\exp_construct_test.cpp(18): or 'void F(B)'
1> while trying to match the argument list '(E)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
संपादित करें: मैं बजना डाउनलोड किया है और बजना-सीएल जो दोनों ही मामलों के लिए त्रुटि की सूचना के साथ संकलित। इसलिए टिप्पणियों में बताया गया है, अस्पष्टता A<short>(short)
और B(E)
के बीच है।
तो शायद वीसी ++ में एक बग है, जब मैं को A(unsigned long)
से हटा देता हूं, तो संकलक किसी भी अस्पष्टता को बढ़ाने के बजाय बी (ई) चुनने के द्वारा चुनता है। क्या कोई मानक अनुपालन के रूप में क्लैंग व्यवहार की पुष्टि कर सकता है, और वीसी ++ छोटी गाड़ी के रूप में?
G(e1_0);
जो किसी भी त्रुटि को उठाने नहीं करता है:
मैं
void G(E) {};
void G(short) {};
और इस तरह जी के लिए एक कॉल गयी। यहां क्यों G(E)
prefferred है, और उम्मीदवारों के मामले में A<short>::A(short)
और B::B(E)
, वे संदिग्ध हैं?
समाप्ति संपादित
धन्यवाद --joja
अगर मैं 'स्पष्ट' को हटा देता हूं, तो यह संकलित नहीं होता है, जो इसे भी नहीं करना चाहिए। संदिग्ध कॉल 'ए :: ए' नहीं बल्कि 'एफ' के लिए है। ध्यान दें कि 'ए :: ए (टी) '' स्पष्ट' नहीं है, इस प्रकार 'एफ' को कॉल संदिग्ध है। यदि आप * ए :: ए (टी) 'के लिए' स्पष्ट 'जोड़ते हैं, तो यह उस रूपांतरण को नियंत्रित करेगा और कोड संकलित होगा। – 5gon12eder
एक कन्स्ट्रक्टर के सामने स्पष्ट कीवर्ड उस प्रकार की ऑब्जेक्ट को केवल एक पैरामीटर के साथ तत्काल तत्काल होने से रोकता है जो कि कन्स्ट्रक्टर तर्क के रूप में कार्य करेगा। जब आप ए के कन्स्ट्रक्टर से 'स्पष्ट' को हटाते हैं, तो आप 'शून्य एफ (ए)' को पास करके एक सरल बना सकते हैं, जो कि एफ (ई 1_0) –
Prismatic
@ 5gon12eder कर रहा है, आप किस कंपाइलर का उपयोग कर रहे हैं? वीएस2013 में यह 'स्पष्ट' के बिना संकलित करता है। मुझे पता है कि संदिग्ध कॉल 'एफ' है, लेकिन इसका कारण 'e1_0' का एक प्रकार है जो' एफ 'का अधिभार स्वीकार करता है। जब 'स्पष्ट' हटा दिया जाता है, तो संकलक रूपांतरण करने के लिए 'बी (ई)' चुनता है और 'एफ (बी)' कॉल करता है। मैंने यह सुनिश्चित करने के लिए 'स्पष्ट' जोड़ा, कि मैं निश्चित रूप से कन्स्ट्रक्टर का उपयोग नहीं करता, जो कि मेरे असली कोड में केवल एक विशेष मामला है। मेरी राय में, 'स्पष्ट' का उपयोग करके कंपाइलर को बी (ई) रूपांतरण का उपयोग करने के लिए और भी मार्गदर्शन करना चाहिए और 'एनम ई' को 'हस्ताक्षरित लंबे' पदोन्नति पर विचार न करें। – joja