एसटीडी का डिफ़ॉल्ट आरंभीकरण :: सरणी?


104

C ++ 11 के साथ std::array, क्या मेरे पास गारंटी है कि वाक्यविन्यास std::array<T, N> x;सरणी के सभी तत्वों को डिफ़ॉल्ट-प्रारंभ करेगा?

संपादित करें : यदि नहीं, तो क्या एक वाक्यविन्यास है जो सभी तत्वों (शून्य-आकार के सरणियों सहित) पर काम करेगा ताकि सभी तत्वों को उनके डिफ़ॉल्ट मान पर आरंभ किया जा सके?

संपादित करें : cppreference पर , डिफ़ॉल्ट निर्माता वर्णन कहता है:

(constructor) (implicitly declared) (public member function)
default-constructs or copy-constructs every element of the array 

तो उत्तर हाँ हो सकता है। लेकिन मैं मानक या भविष्य के मानक के अनुसार निश्चित होना चाहूंगा।


ऐसा मत सोचो। यह डिफ़ॉल्ट रूप से घोषित है, इसलिए यह मूल रूप से T x[N]वाक्यविन्यास के बराबर है ।
रैपर्ट्ज

जवाबों:


149

परिभाषा के अनुसार, डिफ़ॉल्ट इनिशियलाइज़ेशन वह इनिशियलाइज़ेशन है जो तब होता है जब कोई अन्य इनिशियलाइज़ेशन निर्दिष्ट नहीं होता है; C ++ भाषा आपको इस बात की गारंटी देती है कि कोई भी वस्तु जिसके लिए आप एक स्पष्ट इनिशियलाइज़र प्रदान नहीं करते हैं वह डिफ़ॉल्ट आरंभीकृत होगी (C ++ 11 118.5 / 11)। यही कारण है कि प्रकार की वस्तुओं में शामिल हैं std::array<T, N>और T[N]

ध्यान रखें कि ऐसे प्रकार हैं जिनके लिए डिफ़ॉल्ट आरंभीकरण का कोई प्रभाव नहीं होता है और ऑब्जेक्ट के मूल्य को अनिश्चित बना देता है: कोई भी गैर-श्रेणी, गैर-सरणी प्रकार (§8.5 / 6)। नतीजतन, इस प्रकार की वस्तुओं के एक डिफ़ॉल्ट-प्रारंभिक सरणी का अनिश्चित मान होगा, जैसे:

int plain_int;
int c_style_array[13];
std::array<int, 13> cxx_style_array;

दोनों सी-शैली की सरणी और std::arrayअनिश्चित मूल्य के पूर्णांक से भरे हुए हैं, जैसे plain_intअनिश्चित मूल्य है।

क्या कोई सिंटैक्स है जो सभी तत्वों (शून्य-आकार के सरणियों सहित) पर काम करेगा, ताकि सभी तत्वों को उनके डिफ़ॉल्ट मान पर आरंभ किया जा सके?

मैं अनुमान लगा रहा हूं कि जब आप "उनके डिफ़ॉल्ट मूल्य पर" कहते हैं, तो आप वास्तव में "सभी तत्वों को इनिशियलाइज़ T{}" करते हैं। यह डिफ़ॉल्ट-आरंभीकरण नहीं है , यह मूल्य-आरंभीकरण (8.5 / 7) है। आप प्रत्येक घोषणा को एक खाली आरंभीकरण देकर C ++ 11 में आसानी से मूल्य आरंभीकरण का अनुरोध कर सकते हैं:

int plain_int{};
int c_style_array[13]{};
std::array<int, 13> cxx_style_array{};

जो बदले में सरणी के सभी तत्वों को मूल्य-आरंभ कर देगा, जिसके परिणामस्वरूप plain_old_intऔर दोनों प्रकार के सरणियों के सभी सदस्यों को शून्य से आरंभीकृत किया जाएगा।


अगर यह एक वर्ग के सदस्य के बारे में क्या है: संरचना X {std :: सरणी <int, 12> दर्जन; X (): दर्जन () {} क्या मुझे बारह शून्य मिलते हैं?
जेरार्डव

4
@gerardw मानक के अनुसार, हाँ यह करता है। MSVC में कीड़े से सावधान रहें, यह मूल्य आरंभीकरण के कुछ मामलों को सही ढंग से लागू करने में विफल रहता है।
केसी

1
वास्तव में बूस्ट ऐसा कहते हैं और उनके boost::value_initialized लिंक के साथ इसे वर्कअराउंड करते हैं लेकिन मेरा मानना ​​है कि VC12 (VS2013) को अब बेहतर समर्थन मिला है।
v.oddou

1
मुझे इच्छा है कि कॉमेडी ने मानक को डिफ़ॉल्ट मूल्य-आरंभीकरण में बदल दिया और अनुरोध पर मूल्य कम कर दिया। Ie std :: array <int, 12> = {std :: undetermined}; या कुछ और
विक्टर सेहर

व्यवहार में एक अनिश्चित मूल्य के लिए कुछ को इनिशियलाइज़ करने का क्या मतलब है? विकल्प क्या है?
एंड्रयू

21

डिफ़ॉल्ट-आरंभीकरण मानक शब्द से एक शब्द है जिसका अर्थ है कि कोई भी आरंभीकरण नहीं है, इसलिए आपका मतलब शून्य-आरंभीकरण से है

Cppreference.com पर विवरण वास्तव में थोड़ा भ्रामक है। std::arrayएक समग्र वर्ग है, और यदि तत्व प्रकार आदिम है, तो यह POD: "सादा पुराना डेटा," है, जिसमें शब्दार्थ सी भाषा को बारीकी से मिलाता है। का अनुमानित परिभाषित निर्माता std::array< int, N >एक तुच्छ है जो बिल्कुल कुछ भी नहीं करता है।

सिंटेक्स की तरह std::array< int, 3 >()या std::array< int, 3 > x{}जो शून्य मान प्रदान करते हैं, एक निर्माता को आमंत्रित करके ऐसा नहीं करते हैं। शून्य प्राप्त करना मूल्य-आरंभ का हिस्सा है , जो C ++ 11 /8.5 / 8 में निर्दिष्ट है:

टी प्रकार की एक वस्तु को महत्व देने के लिए इसका मतलब है:

- यदि T उपयोगकर्ता-प्रदान या हटाए गए डिफ़ॉल्ट निर्माता के बिना एक (संभवतः cv-योग्य) वर्ग प्रकार है, तो ऑब्जेक्ट शून्य-आरंभीकृत है ... और यदि T में एक गैर-तुच्छ डिफ़ॉल्ट निर्माता है, तो ऑब्जेक्ट डिफ़ॉल्ट-आरंभीकृत है;

std::arrayकोई उपयोगकर्ता-प्रदान डिफ़ॉल्ट निर्माता नहीं है, इसलिए यह शून्य-आरंभिक हो जाता है। इसमें एक अंतर्निहित परिभाषित डिफ़ॉल्ट निर्माता है, लेकिन यह तुच्छ है, इसलिए यह कभी भी डिफ़ॉल्ट-प्रारंभिक नहीं है। (लेकिन इससे कोई फर्क नहीं पड़ता क्योंकि परिभाषा के अनुसार तुच्छ आरंभीकरण का रनटाइम पर कोई प्रभाव नहीं पड़ता है।)

यदि नहीं, तो क्या कोई वाक्यविन्यास है जो सभी तत्वों (शून्य-आकार के सरणियों सहित) पर सभी तत्वों को उनके डिफ़ॉल्ट मान पर आरंभ करने के लिए काम करेगा?

C- शैली सरणियाँ और std::arrayदोनों समुच्चय हैं, और किसी भी समुच्चय को पूरी तरह से शून्य-आरंभ करने का तरीका वाक्यविन्यास के साथ है = {}। यह C ++ 98 के बाद से काम करता है। ध्यान दें कि C- शैली सरणियों में शून्य सीमा नहीं हो सकती है, और sizeof (std::array< X, 0 >)यह शून्य नहीं है।


6

सरणी के प्रत्येक तत्व को दोनों T x[N];और std::array<T, N> x;डिफ़ॉल्ट-आरंभ करें।

उदाहरण के लिए, यदि T = std::string, हर तत्व एक खाली स्ट्रिंग होगा। यदि Tएक डिफ़ॉल्ट निर्माता के बिना एक वर्ग है, तो दोनों संकलन करने में विफल रहेंगे। यदि T = int, प्रत्येक तत्व का अनिश्चित मान होगा (जब तक कि घोषणा नाम स्थान के दायरे में नहीं होगी)


0

सबसे पहले, T x [N] डिफ़ॉल्ट रूप से तत्वों को इनिशियलाइज़ करता है, हालाँकि एक स्केलर टाइप T का डिफ़ॉल्ट इनिशियलाइज़ेशन वास्तव में कुछ नहीं करता है। ऊपर भी std :: array x के लिए है। मुझे लगता है कि आपको सूची आरंभीकरण की आवश्यकता है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.