2016-01-20 11 views
6
#include <iostream> 
#include <string> 
#include <typeinfo> 
#include <typeindex> 
#include <map> 
#include <vector> 

class Base{ 
public: 
    virtual ~Base() {} 

}; 

class Derived: public Base { }; 

int main(){ 

    int arr[10]; 
    Derived d; 
    Base *p = &d; 

    std::map<std::type_index, std::string> proper_name = { 
     {typeid(int), "int"}, {typeid(double), "double"}, {typeid(float), "float"}, {typeid(char), "char"}, 
     {typeid(Base), "Base"}, {typeid(Derived), "Derived"}, {typeid(std::string), "String"}, 
     {typeid(int[10]), "Ten int Array"}, {typeid(p), "Base Pointer"}}; 

} 

मैं इस सूची-प्रारंभिकरण में होने वाले निहित रूपांतरणों को समझने की कोशिश कर रहा हूं। N3337 के 13.3.1.7 से:सूची-प्रारंभिक एक अंतर्निहित रूपांतरण है?

  1. प्रारंभ में, उम्मीदवार:

    गैर कुल वर्ग प्रकार टी की वस्तुओं सूची-प्रारंभ कर रहे हैं (8.5.4), अधिभार संकल्प दो चरणों में निर्माता का चयन करता है कार्य कक्षा टी के प्रारंभकर्ता-सूची निर्माता (8.5.4) हैं और तर्क सूची में प्रारंभिक सूची को एक तर्क के रूप में शामिल किया गया है।

  2. यदि कोई व्यवहार्य प्रारंभकर्ता-सूची निर्माता नहीं मिला है, तो ओवरलोड रिज़ॉल्यूशन फिर से किया जाता है, जहां उम्मीदवार कार्य कक्षा टी के सभी निर्माता होते हैं और तर्क सूची प्रारंभकर्ता सूची के तत्व होते हैं।

8.5.4:

एक निर्माता अगर अपनी पहली पैरामीटर प्रकार std::initializer_list<E> या संदर्भ के लिए संभवतः सीवी योग्य std::initializer_list<E> कुछ प्रकार E के लिए की है एक प्रारंभकर्ता-सूची निर्माता है, और या तो देखते हैं कोई अन्य पैरामीटर या अन्य सभी पैरामीटर में डिफ़ॉल्ट तर्क

तो std::map के लिए रचनाकारों की सूची

map (initializer_list<value_type> il, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type());

उम्मीदवार समारोह है, value_type इस मामले में pair<const type_index, std::string> है। अन्त में 13.3.3.1.5 से:

तो पैरामीटर प्रकार std::initializer_list<X> या 135 और सभी प्रारंभकर्ता सूची के तत्वों "X की सरणी" है परोक्ष X में बदला जा सकता, अंतर्निहित रूपांतरण अनुक्रम सबसे खराब रूपांतरण एक कन्वर्ट करने के लिए आवश्यक है सूची का तत्व X पर।

तो यह एक वैध रूपांतरण है जब तक कि ब्रेसिड-सूची के तत्व निहित रूप से pair<const type_index, std::string> में परिवर्तित हो जाते हैं। लेकिन उन तत्वों को भी ब्रेसिड किया जाता है-खुद को सूचीबद्ध करता है। Pair प्रारंभकर्ता-सूची कन्स्ट्रक्टर नहीं लेता है, from here ऐसा लगता है कि एक ब्रसेड-इनिट सूची से प्रति-प्रारंभिकरण ऑब्जेक्ट बनाने के लिए 13.3.1.7 के दूसरे भाग का उपयोग करता है। तो निम्नलिखित:

pair<const type_index, std::string> p = {typeid(int), "int"} 

हो जाता है:

pair<const type_index, std::string> p(typeid(int), "int") 

लेकिन यह एक अंतर्निहित रूपांतरण माना जाता है? दो तर्क वाले कन्स्ट्रक्टर का उपयोग कैसे एक अंतर्निहित रूपांतरण माना जा सकता है? इस पर मानक की टिप्पणियां क्या हैं?क्योंकि पहले बयान कॉपी-सूची-प्रारंभ है, जबकि दूसरी डायरेक्ट-प्रारंभ है

उत्तर

3

आपका निष्कर्ष है कि

pair<const type_index, std::string> p = {typeid(int), "int"}; 

pair<const type_index, std::string> p(typeid(int), "int"); 

हो जाता है सही नहीं है। दोनों समान हैं, सिवाय इसके कि प्रति-सूची-प्रारंभिकता खराब है यदि explicit कन्स्ट्रक्टर चुना गया है (और पूर्व में रूपांतरण को सीमित करने की अनुमति नहीं है)।

तो अगर सवाल में pair निर्माता के रूप में

template<class U1, class U2> 
explicit constexpr pair(U1&& x, U2&& y); 

डायरेक्ट-प्रारंभ अभी भी कामयाब होने की परिभाषित किया गया था, लेकिन कॉपी-सूची-प्रारंभ विफल हो जाएगा। सही [over.match.list] के कुछ हिस्सों के नीचे से हवाला देते हुए आप

उद्धृत कॉपी-सूची-प्रारंभ में, अगर एक explicit निर्माता चुना जाता है, प्रारंभ बीमार ही बना है।


उसके अलावा, सब कुछ आप जो बोलते हैं उसे सही है। pair कन्स्ट्रक्टर एक अंतर्निहित रूपांतरण है क्योंकि कन्स्ट्रक्टर explicit नहीं है और इसे [over.match.list] की दूसरी बुलेट के अनुसार ओवरलोड रिज़ॉल्यूशन के लिए माना जाता है क्योंकि pair में प्रारंभकर्ता सूची निर्माता नहीं है।

+2

नाइटपिक: "दोनों समान हैं, सिवाय इसके कि कॉपी-सूची-प्रारंभिकता एक स्पष्ट कन्स्ट्रक्टर चुना गया है, तो बीमार हो गया है", [जब प्रारंभकर्ता सूची में एक तत्व होता है, जिसका प्रकार टाइप से समान या व्युत्पन्न होता है ऑब्जेक्ट को प्रारंभ किया जा रहा है] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467) (जो अपवाद के अपवाद के लिए अपवाद हो सकता है अगर [प्रारंभकर्ता_सूची है निर्माता] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2137))। –

+0

@ टी.सी. धन्यवाद, मैं उनमें से किसी के बारे में नहीं जानता था। लेकिन अब जब पहले मुद्दे में एक संकल्प है, मैंने जो कहा वह अभी भी सही है, है ना? दो मतभेद स्पष्ट रचनाकार हैं और रूपांतरण को संकुचित करते हैं। – Praetorian

+0

हाँ, मुझे लगता है, अभी के लिए। कॉपी-लिस्ट और कॉपी-वेनिला अधिक अलग हैं। –

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