2017-08-28 51 views
6

मैं हाल ही में एक सी ++ प्रोजेक्ट पर काम कर रहा था और स्ट्रिंग कंस्ट्रक्टर के साथ एक एज केस में आया था जिसे मैं पूरी तरह से समझ नहीं सकता। इस प्रकार प्रासंगिक कोड (जो you can run here) है:यह कोड एक वर्ण में एक स्ट्रिंग को प्रारंभ करने के लिए प्रारंभकर्ता_सूची कन्स्ट्रक्टर क्यों कॉल करता है?

#include <iostream> 
#include <string> 
using namespace std; 

int main() { 
    string directParens(1, '*'); 
    string directBraces{1, '*'}; 
    string indirectBraces = {1, '*'}; 

    cout << directParens.size() << endl; // 1 
    cout << directBraces.size() << endl; // 2 
    cout << indirectBraces.size() << endl; // 2 
    return 0; 
} 

तार की ब्रेस-प्रारंभ संस्करणों उन में दो पात्रों को खत्म, अर्थात्, संख्यात्मक मान 1 के साथ एक char एक स्टार का स्थान है।

मुझे समझ में नहीं आ रहा है कि स्ट्रिंग के ब्रेस-प्रारंभिक संस्करणों ने आकार और चरित्र में लेने वाले निर्माता के बजाय initializer_list कन्स्ट्रक्टर का आह्वान क्यों किया। initializer_list निर्माता इस हस्ताक्षर है:

basic_string(std::initializer_list<CharT> init, 
      const Allocator& alloc = Allocator()); 

यह देखते हुए कि stringbasic_string चार के लिए एक उपनाम है, विशिष्ट हस्ताक्षर होगा

string(std::initializer_list<char> init, 
     const Allocator& alloc = Allocator()); 

कैसे है प्रारंभकर्ता {1, '*'}, जो प्रकार int के लोग, दोनों शामिल है और इस कन्स्ट्रक्टर से मेल खाने वाले char टाइप करें? मैं इस धारणा के तहत था कि std::initializer_list में सभी अक्षरों का एक ही प्रकार होना चाहिए - क्या यह गलत है?

+1

नोट, रूपांतरणों को संकुचित करने के लिए एक अपवाद है [निरंतर अभिव्यक्ति के लिए जिसका परिणाम रूपांतरण के बाद लक्ष्य प्रकार में फिट होगा] (https://stackoverflow.com/a/26974911/1708801) –

उत्तर

15

प्रारंभकर्ता {1, '*'} कैसे प्रारंभ होता है, जिसमें इस कन्स्ट्रक्टर से मेल खाने वाले प्रकार int और प्रकार char दोनों तत्व होते हैं?

क्योंकि दोनों शाब्दिक 1 और चरित्र '*' एक संकुचन रूपांतरण का उपयोग किए बिना char के लिए परिवर्तनीय हैं। इसलिए, वे initializer_list<char> कन्स्ट्रक्टर को कॉल करने के योग्य हैं। और initializer_list कन्स्ट्रक्टर सूची प्रारंभिकरण का उपयोग करते समय हमेशा प्राथमिकता है। यदि पैरामीटर से initializer_list कन्स्ट्रक्टर को कॉल करना संभव है, तो यह होगा।

कभी कंटेनर जब तक आप सूची में तत्वों का इरादा के साथ braced-init-सूचियों का उपयोग तत्वों कंटेनर के किया जाना है। यदि आप उन्हें कन्स्ट्रक्टर पैरामीटर बनाने का इरादा रखते हैं, तो एक कन्स्ट्रक्टर का उपयोग करें।

+0

Ah, gotcha। तो एक ब्रेस प्रारंभकर्ता को प्रारंभकर्ता_सूची के रूप में व्याख्या किया जाएगा यदि सभी तत्वों को रूपांतरण को संकुचित किए बिना अंतर्निहित प्रकार में परिवर्तित किया जा सकता है। पुष्टि करने के लिए, क्या इसका मतलब यह होगा कि {3, 3.0} को प्रारंभकर्ता_सूची के रूप में व्याख्या किया जा सकता है, लेकिन प्रारंभकर्ता_सूची नहीं? और {INT_MAX, '*'} एक प्रारंभकर्ता_सूची हो सकता है? – templatetypedef

+0

@templatetypedef: ठीक है, '{INT_MAX, '*'}' उदाहरण * एक 'startizer_list ' नहीं हो सकता है, क्योंकि 'INT_MAX' को एक संकीर्ण रूपांतरण के बिना' char' में परिवर्तित नहीं किया जा सकता है। लेकिन अन्यथा, आप सही हैं। –

+0

ओह, मैंने सोचा कि * प्रकार * पर लागू संकुचन रूपांतरण, * मूल्य नहीं है। * यह चीज़ों को साफ़ करता है! धन्यवाद! – templatetypedef

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