2013-01-21 22 views
5

में लूप के लिए रेंज-आधारित यह ऐसा प्रतीत होता है कि सी ++ 11 में उपलब्ध वाक्यविन्यास के प्रत्येक "शैली के लिए" सरणी के वास्तविक आकार (तत्वों की संख्या) के ज्ञान के बिना सरणी पुनरावृत्ति को अनुमति देता है। मुझे लगता है, क्योंकि यह नए मानक का हिस्सा है, यह सी सरणी के लिए भी पूरी तरह से सुरक्षित है। आमतौर पर, आप भी अलग से यह जोड़ तोड़ से पहले एक सी सरणी के आकार को पता होना चाहिए, लेकिन मैं सत्यापन चाहते किसी को भी इस नई सी ++ तकनीक है कि यह वास्तव में काम करता है के रूप में आप उम्मीद थी के साथ अनुभव से:सी ++

extern float bunch[100]; 

for (float &f : bunch) { 
    f += someNumber; 
} 

क्या मैं है इस तकनीक के लिए स्पष्ट स्पष्ट प्रभाव या नुकसान के बारे में पता होना चाहिए? यह मुझे दिखाई देने वाले कोड में बहुत कुछ नहीं दिखाता है, संभवतः क्योंकि अधिकांश कोड मानक में होने से पहले लिखा गया था। यह सुनिश्चित करना चाहते हैं कि इसका दुर्लभ उपयोग किसी अन्य कारण से नहीं है, जिसे जाना जाता है।

+10

आप हमेशा एक सरणी के आकार (https://gist.github.com/3959946#file-arrays-h-L33) को जान सकते हैं। यदि आप इसे सूचक में परिवर्तित करते हैं, तो आप आकार को जानना बंद कर देते हैं। –

+1

@ आर। मार्टिन्होफर्नैंड्स: अच्छा गिस्ट! –

+2

सामान्य रूप से आप पूर्वगामी सादे सरणी द्वारा पूर्व में सी ++ जीवन जीते हैं और मानक पुस्तकालय कंटेनर –

उत्तर

4

उस उपयोग के बारे में अजीब या असुरक्षित कुछ भी नहीं है। सरणी का आकार संकलन समय पर जाना जाता है, इसलिए इसे लूप में उपयोग किया जा सकता है।

template< class T, std::size_t N > 
std::size_t length(const T (&)[N]) 
{ 
    return N; 
} 

Foo f[5]; 
std::cout << length(f) << "\n"; 

यह यह स्पष्ट करना चाहिए कि आप गतिशील रूप से आकार सी-शैली पर इस तकनीक का, या श्रेणी के आधार छोरों, उपयोग नहीं कर सकते कि यह एक टेम्पलेट समारोह का एक उदाहरण आप एक सरणी की लंबाई पता लगाने के लिए अनुमति देता है सरणियों।

बेशक

, यदि आप रेंज आधारित छोरों तो आप भी std::array होना चाहिए (यदि नहीं, तो आप शायद ti std::tr1 या बढ़ावा से प्राप्त कर सकते हैं), तो आप सी-शैली सरणी पूरी तरह से बच सकते हैं:

extern std::array<float, 100> bunch; 

for (auto &f : bunch) { 
    f += someNumber; 
} 
+0

आह, शायद मेरा भ्रम तो सी सरणी और 'std :: array' के बीच का अंतर है - श्रेणी आधारित बाद के लिए मान्य है, लेकिन पूर्व के लिए नहीं, है ना? क्योंकि मैंने हमेशा सोचा और पढ़ा था कि एक सी सर अपने आकार (लंबाई) – johnbakers

+1

@ सेबीबी जोहान्स संख्या के बारे में ज्ञान प्रदान नहीं करता है, यह दोनों के लिए मान्य है, जब तक सी-शैली सरणी स्थिर रूप से आकार में हो। उपरोक्त टेम्पलेट फ़ंक्शन आपको दिखाता है कि आप आकार को इस तरह के सरणी से वापस प्राप्त कर सकते हैं। – juanchopanza

+0

दूसरे शब्दों में यह ढेर पर एक सरणी पर काम करता है, ढेर पर नहीं, है ना? – johnbakers

2

Arrays संदर्भ के रूप में पारित किया जा सकता है और उनके प्रकार और लंबाई का अनुमान लगाया जा सकता है।

#include <iostream> 

template<typename T, size_t N> 
void fun(T const (&arr)[N]) 
{ 
    for (std::size_t i = 0; i < N; ++i) 
     std::cout << arr[i] << " "; 
} 

int main() 
{ 
    int x[] = { 1, 2, 3 }; // no need to set length here 
    fun(x); // 1 2 3, no need to specify type and length here 
} 
+1

पर जा रहे हैं यह इस टेम्पलेट को देखने में मुझे अस्पष्ट है कि 'एन' के लिए' size_t' फ़ंक्शन 'मजेदार' में कैसे पारित किया गया है - यह 'एन' के लिए मूल्य कैसे निकाला जा रहा है? – johnbakers

+0

टेम्पलेट तर्क कटौती के दौरान, कंपाइलर तर्क (x जो प्रकार int [3] है) और औपचारिक पैरामीटर (एआर जो प्रकार टी [एन] है) और टी के लिए int को प्रतिस्थापित करने के लिए एन को सटीक देता है मैच। – TemplateRex

+0

@ सेबेबी जोहान्स निश्चित आकार सरणी के प्रकार में आकार शामिल है। तो आप इसे प्राप्त करने के लिए टेम्पलेट पैरामीटर कटौती का उपयोग करें। – juanchopanza

4

एरे के साथ एक श्रेणी-आधारित-लूप का उपयोग करना पूरी तरह से सुरक्षित है। मुझे लगता है कि यदि आप चिंतित हैं कि आप गलती से एक सूचक पर इसका इस्तेमाल कर सकते हैं कर रहे हैं:

float* array = new float[100]; 
for (float& f : array) { 
    // ... 
} 

हालांकि चिंता मत करो। कंपाइलर इस मामले में एक त्रुटि उत्पन्न करेगा। तो ऐसे मामलों में जहां यह सुरक्षित नहीं है, आपको वैसे भी संकलन त्रुटि मिल जाएगी।

+0

वैसे भी 'नई [] 'का उपयोग करने के लिए वह अपनी खुद की गूंगा गलती होगी। – Puppy

+0

@DeadMG 'नई फ्लोट [100] 'के साथ क्या गलत है? – johnbakers

+1

@DeadMG: "गूंगा" "अनजान" जैसा नहीं है। –