सबसे पहले, कुछ बहुत ही महत्वपूर्ण: आप कंस्ट्रक्टर्स दो भिन्न प्रकार की है। विशेष रूप से पहले, C(std::initializer_list<int>)
को आरंभकर्ता-सूची कन्स्ट्रक्टर कहा जाता है। दूसरा सिर्फ एक सामान्य उपयोगकर्ता परिभाषित कन्स्ट्रक्टर है।
[dcl.init.list]/p2
एक निर्माता, अगर अपनी पहली पैरामीटर प्रकार std::initializer_list<E>
या संदर्भ के लिए संभवतः सीवी योग्य std::initializer_list<E>
कुछ प्रकार E
के लिए की है एक प्रारंभकर्ता-सूची निर्माता है और या तो कोई अन्य पैरामीटर नहीं हैं या अन्य सभी पैरामीटर में डिफ़ॉल्ट तर्क हैं (8.3.6)।
एक सूची-आरंभीकरण एक या अधिक प्रारंभकर्ता-खंड युक्त में, प्रारंभकर्ता-सूची कंस्ट्रक्टर्स किसी अन्य निर्माताओं से पहले माना जाता है। यही है, शुरुआतकर्ता सूची सूची निर्माता अधिभार संकल्प के दौरान प्रारंभिक उम्मीदवार हैं।
[over.match.list]/p1
गैर कुल वर्ग प्रकार T
की वस्तुओं सूची-प्रारंभ 8.5.4 निर्दिष्ट करता है ऐसी है कि कि अधिभार संकल्प इस खंड में नियमों के अनुसार किया जाता है कर रहे हैं , अधिभार संकल्प दो चरणों में निर्माता का चयन करता है:
प्रारंभ में, उम्मीदवार कार्यों वर्ग T
और तर्क सूची के प्रारंभकर्ता-सूची कंस्ट्रक्टर्स (8.5.4) एक एकल तर्क के रूप में प्रारंभकर्ता सूची के होते हैं ।
यदि कोई व्यवहार्य प्रारंभकर्ता-सूची निर्माता पाया जाता है, अधिभार संकल्प फिर से है, जहां उम्मीदवार कार्यों वर्ग T
के सभी निर्माणकर्ता और तर्क सूची तत्वों प्रारंभकर्ता सूची के के होते हैं किया जाता है।
तो c1
और c2
के दोनों घोषणाओं के लिए उम्मीदवार सेट केवल C(std::initializer_list<int>)
निर्माता के होते हैं।
कन्स्ट्रक्टर का चयन करने के बाद तर्कों का मूल्यांकन यह देखने के लिए किया जाता है कि क्या उन्हें पैरामीटर प्रकारों में परिवर्तित करने के लिए एक अंतर्निहित रूपांतरण अनुक्रम मौजूद है या नहीं। यह प्रारंभकर्ता-सूची रूपांतरण के लिए नियमों को करने के लिए हमें ले जाता है:
[over.ics.list]/p4 (जोर मेरा):
अन्यथा, यदि पैरामीटर प्रकार std::initializer_list<X>
और सभी के तत्वों है प्रारंभकर्ता सूची को X
में पूर्ण रूप से परिवर्तित किया जा सकता है, अंतर्निहित रूपांतरण अनुक्रम सूची के तत्व को X
में परिवर्तित करने के लिए आवश्यक सबसे खराब रूपांतरण है, या यदि प्रारंभकर्ता सूची में कोई तत्व नहीं है, तो पहचान रूपांतरण।
इसका मतलब है कि एक रूपांतरण मौजूद है यदि प्रारंभकर्ता सूची के प्रत्येक तत्व को int
में परिवर्तित किया जा सकता है।
अब के लिए c1
पर आइए फोकस: प्रारंभकर्ता-सूची {{1, 2}, {3}}
के लिए, प्रारंभकर्ता-खंड {3}
int
में बदला जा सकता ([over.ics.list] /p9.1), लेकिन नहीं {1, 2}
(यानी int i = {1,2}
बीमार है -formed)। इसका मतलब है उपरोक्त उद्धरण के लिए शर्त का उल्लंघन किया जाता है। चूंकि कोई रूपांतरण है, अधिभार संकल्प विफल रहता है के बाद से वहाँ कोई अन्य व्यवहार्य निर्माता ये हैं और हम [over.match.list] की/p1 दूसरे चरण के लिए वापस लिया जाता है:
- कोई व्यवहार्य प्रारंभकर्ता-सूची तो कन्स्ट्रक्टर पाया जाता है, ओवरलोड रिज़ॉल्यूशन फिर से किया जाता है, जहां उम्मीदवार कार्य कक्षा
T
के सभी रचनाकार होते हैं और तर्क सूची में प्रारंभकर्ता सूची के तत्व होते हैं।
अंत में शब्द में परिवर्तन पर ध्यान दें। दूसरे चरण में तर्क सूची अब एक प्रारंभिक-सूची नहीं है, लेकिन घोषणा में उपयोग की गई ब्रांस्ड-इनिट-सूची के तर्क। इसका अर्थ यह है कि हम प्रारंभिक रूपांतरण-सूचियों के संदर्भ में अंतर्निहित रूपांतरणों का मूल्यांकन कर सकते हैं व्यक्तिगत रूप से एक ही समय के बजाय।
प्रारंभकर्ता-सूची {1, 2}
में, दोनों प्रारंभकर्ता-खंड, int
में बदला जा सकता है ताकि पूरे प्रारंभकर्ता-खंड initializer_list<int>
, {3}
के लिए एक ही बदला जा सकता है। अधिभार संकल्प को दूसरे कन्स्ट्रक्टर के साथ चुना जा रहा है।
अब c2
पर ध्यान केंद्रित करें, जो अब आसान होना चाहिए। प्रारंभकर्ता-सूची निर्माता का पहले मूल्यांकन किया जाता है, और, { {1}, {2} }
का उपयोग करके int
पर {1}
और {2}
से रूपांतरण निश्चित रूप से मौजूद है, इसलिए पहला कन्स्ट्रक्टर चुना गया है।
नहीं है, क्यों मैं दूसरे कन्स्ट्रक्टर को 'सी (std :: startizer_list, std :: startizer_list ) में बदल दूंगा और 'सी 2' {सी c2 {{1.0}, {2}} को' c2' घोषणा; 'मैं संकलक प्राप्त करूंगा त्रुटि? आपके उत्तर के अनुसार इस के लिए दूसरा कन्स्ट्रक्टर चुना जाना चाहिए। या मुझे गलत निष्कर्ष निकाला गया था? [लाइव डेमो] (http://coliru.stacked-crooked.com/a/e299e66462e220cf) –
alexolut
@alexolut [over.isc.list]/p4: "[...] और प्रारंभकर्ता सूची के सभी तत्व कर सकते हैं स्पष्ट रूप से 'एक्स' में परिवर्तित हो जाएं," ए 'डबल' को निश्चित रूप से 'int' में परिवर्तित किया जा सकता है, इसलिए इस खंड में। आगे पढ़ना: "अंतर्निहित रूपांतरण अनुक्रम सूची के तत्व को 'एक्स'' में परिवर्तित करने के लिए आवश्यक सबसे खराब रूपांतरण है। यह निहित रूपांतरण अनुक्रम * संकुचित रूपांतरण अनुक्रम * है। तो ऐसा नहीं है कि एक व्यवहार्य प्रारंभकर्ता सूची निर्माता नहीं मिला (चरण 2 पर जाने का मतलब है कि हमें एक नहीं मिला है), यह है कि रूपांतरण स्वयं प्रोग्राम को खराब बना देता है। – 0x499602D2
आईई। व्यावहारिक कन्स्ट्रक्टर पाया गया था, लेकिन तर्क रूपांतरण स्वयं व्यवहार्य नहीं है (बीमार गठित)। इस मामले में हम दूसरे चरण तक नहीं पहुंच पाए हैं। - क्या मैं इसे सही समझता हूँ? – alexolut