2012-11-13 16 views
9

जब मैं कुछ इस तरह करते हैं:लूप के लिए सी ++ 11 श्रेणी-आधारित कैसे सरणी आकार को जानता है?

int my_array[5] = {1, 2, 3, 4, 5}; 
for (int &x : my_array) { 
    x *= 2; 
} 

सी ++ 11 स्पष्ट रूप से जानता है कि मेरी सरणी केवल 5 तत्व है। क्या यह जानकारी my_array ऑब्जेक्ट में कहीं भी संग्रहीत है?

यदि हां, तो क्या कोई अच्छा कारण है कि यह डेवलपर के रूप में मेरे लिए उपलब्ध नहीं है (या यह है?!?!?)? ऐसा लगता है कि अगर सी ++ देव हमेशा उन सरणी की सीमाओं को जानते हैं जो वे काम कर रहे हैं तो दुनिया की कई समस्याओं का समाधान किया जाएगा।

उत्तर

11

यह केवल कुछ ऐसा है जो भाषा को काम करने की आवश्यकता होती है, और संकलक को कार्यान्वित करना होगा। जाहिर है कि my_array का पूरा प्रकार int[5] है (यानी आकार प्रकार का हिस्सा है), इसलिए यह जानकारी आसानी से उपलब्ध है।

आम धारणा के विपरीत, वहाँ, है खेल में मुक्त std::begin()/std::end() कार्यों का कोई उपयोग हालांकि उन भोलेपन से (लेकिन वहाँ है कि इस दृष्टिकोण टूट जाएगा ADL से जुड़े एक पकड़ने है) चाल करने के लिए सक्षम होने के लिए प्रतीत होता है ।

+0

ठीक है:

यहाँ एक उदाहरण आकार समारोह है। तो क्या कोई विशेष कारण है कि my_array.size मौजूद नहीं है? – MrFox

+6

@ सुस्लिक: निश्चित रूप से, क्योंकि सरणी कक्षा प्रकार नहीं हैं और इस प्रकार सदस्य कार्य नहीं हो सकते हैं। लेकिन आप एक 'array_size' मुक्त फ़ंक्शन टेम्पलेट लिख सकते हैं जो वांछित मान उत्पन्न करता है, या आसानी से निर्मित ['std :: limit'] (http://en.cppreference.com/w/cpp/types/extent का उपयोग करें))। –

+0

मैं अपने जीवन को इतनी देर तक इस बारे में नहीं जानता था ... मैं std :: vector blame :)। – MrFox

5

नहीं, यह वस्तु का हिस्सा नहीं है। लेकिन यह इस प्रकार का हिस्सा है। सरणी घोषणा में 5 यही है। बहरहाल, यह काम नहीं करेगा:

void f(int arr[5]) { 
    for(int& x: arr) { 
     // whatever 
    } 
} 

क्योंकि सरणी के नाम यहाँ अपनी पहली तत्व के लिए सूचक में decays, कि है, तर्क घोषणा int *arr जो कोई आकार जानकारी नहीं है के बराबर है।

+3

मैं इस उदाहरण में 'क्षय' शब्द का उपयोग नहीं करता। मुझे लगता है कि यह शब्द आमतौर पर कई अभिव्यक्तियों में एक सरणी चर के लिए किए गए निहित रूपांतरण के लिए विशिष्ट होता है। 'int एक [5]; ए + 1; // decay' इसके बजाय मैं यह संदर्भ देना चाहता हूं कि 'समायोजन' शब्द के साथ क्या होता है क्योंकि यह मानक उपयोग शब्द है। 'शून्य फू (int एक [5]); // प्रकार 'समायोजन': शून्य फू के बराबर (int * ए) '। और जब मैं शब्द कहता हूं तो मैं एक व्यंग्यात्मक स्वर का उपयोग करना पसंद करता हूं। – bames53

+0

हालांकि यह काम करेगा। 'शून्य एफ (int (और arr) [5]) {...}' – balki

+0

संदर्भ के लिए, @ बाल्कि का समाधान unsized सरणी संदर्भों के साथ काम नहीं करता है, उदा। '(और आगमन) [5]'। लेकिन आमतौर पर इसे टेम्पलेट पैरामीटर के रूप में सरणी आकार का उपयोग करके सामान्य आकार के सरणी के लिए काम करने के लिए बनाया जा सकता है: https://stackoverflow.com/questions/26182907/range-based-for-loop-on-array-passed- टू-गैर-मुख्य-फ़ंक्शन – andybuckley

6

यह उपलब्ध है - आप मानक सी ++ में सरणी पर begin और end परिभाषित कर सकते हैं। सरणी का आकार प्रकार में एन्कोड किया गया है।

सामान्य विधि सरणी के संदर्भों का उपयोग करना है।

template<typename T, size_t N> 
size_t array_size(T (& const)[N]) 
{ 
    return N; 
} 
+6

इसे 'std :: limit' के रूप में भी जाना जाता है।और 'std :: start' और 'std :: end' * पहले से ही * मानक लाइब्रेरी में सरणी के लिए परिभाषित हैं। –