2015-06-29 3 views
5

मेरे पास अभी एक त्वरित प्रश्न है। मैं पॉइंटर को वांछित संख्या में प्रगति जोड़ने पर std::next का उपयोग करने के लाभों का आकलन नहीं कर सकता। एक साधारण उदाहरण:पॉइंटर को पूर्णांक जोड़ने के बजाय std :: का उपयोग क्यों करें?

int main() 
{ 
    int arr [] = {1, 2, 3, 4, 5}; 
    cout << *(arr + 2) << ", "; //example 1 
    cout << *std::next(arr, 2) << endl; //example 2 
    return 0; 
} 

आउटपुट: 3, 3

तार्किक रूप से, उदाहरण 1 तेज, के बाद से कोई समारोह इसके अलावा, कहा जाता है आदि, उदाहरण है, जिसमें मैं इस कोड भाग गया में, अगर मैं एक जोड़ा जाना चाहिए संख्या जो सूचक को सीमाओं से बाहर होने का कारण बनती है (उदाहरण के लिए 7), कंपाइलर उदाहरण 1 में एक त्रुटि फेंक देगा, लेकिन खुशी से आगे बढ़ेगा और मुझे उदाहरण में एक मेमोरी एड्रेस देगा। इसने विरोधाभास किया कि मैंने पहले क्या सोचा था: std::next पॉइंटर सीमा से बाहर होने पर कुछ प्रकार की चेतावनी या कुछ देगा।

किसी भी ज्ञान की सराहना की जाएगी।

+0

यह कहने की तरह है: "हम सरणी के बजाय वेक्टर का उपयोग क्यों कर रहे हैं?"। 'Std :: अगला' सभी इटरेटर प्रकारों के साथ काम करता है, न सिर्फ कच्चे पॉइंटर्स। –

उत्तर

9

क्योंकि std::next न केवल कच्चे पॉइंटर्स पर काम करने के लिए डिज़ाइन किया गया है बल्कि सभी इटरेटर पर, इसलिए यह अधिक बहुमुखी है।

आपकी धारणा भी झूठी है। उचित अनुकूलन स्तर का उपयोग करते समय दोनों दृष्टिकोण एक ही असेंबली में परिणामस्वरूप होंगे। फिर, सी ++ इस तरह के अनुकूलन को आसान बनाने के लिए डिज़ाइन किया गया है। आपके उदाहरण में अंतर्निहित पुनरावर्तक प्रकार एक कच्चा सूचक है, जाहिर है, और यह समझने के लिए काफी छोटा है कि फ़ंक्शन कॉल को रेखांकित किया जा सकता है।

संपादित करें:

के रूप में मैट ने कहा कि उनकी टिप्पणी में, वहाँ सिर्फ एक फैंसी नाम और एक टेम्पलेट आवरण से iterators के लिए और अधिक कर रहे हैं। डेटा संरचनाएं (कंटेनर) हैं जो एक संगत मेमोरी सेगमेंट में नहीं रहती हैं (उदा। map या set) स्मृति में सटीक प्लेसमेंट को जानने के लिए उन्हें अधिक तर्क का उपयोग करने की आवश्यकता है। इटरेटर भी इसे लपेटते हैं, वे एल्गोरिदम और कंटेनर के बीच अमूर्त स्तर प्रदान करते हैं।

तो मानक मुहावरे का उपयोग करके, ऊपर दिए गए बिंदुओं को जोड़ना, अधिक मजबूत कोड लिखने में मदद करता है, यानी विभिन्न प्रकार के कंटेनर (उनकी मेमोरी लेआउट की परवाह नहीं करते) का समर्थन करने में मदद करता है, जबकि काफी स्मार्ट कंपाइलर्स के कारण संभव हो सकता है।

+4

विशेष रूप से, इटरेटर जो यादृच्छिक पहुंच का समर्थन नहीं करते हैं और इसलिए पूर्णांक के साथ 'ऑपरेटर +' नहीं। –

+0

पहला उदाहरण एक त्रुटि क्यों फेंक देगा, और दूसरा नहीं? मैं वीसी ++ 2013 का उपयोग कर रहा हूं। विशेष रूप से यह "अनियमित स्थानीय चर 'arr' प्रयुक्त" कहता है। –

+0

@MattMcNabb मैं आपकी टिप्पणी के बाद सहमत हूं, मैंने फैसला किया है कि इसके बारे में कुछ विस्तार करना उचित है। उम्मीद है कि यह तस्वीर को धुंधला नहीं करता है। – luk32

7

std::next सभी इटरेटर प्रकारों के साथ काम करता है। यदि आप जानते हैं कि आप एक सरणी से निपट रहे हैं, तो मूल्य जोड़ना ठीक काम करता है। हालांकि, अगर आप एक सामान्य कार्य लिख रहे हैं जिसे आप विभिन्न प्रकार के इटरेटर पर काम करना चाहते हैं, तो यह एक समस्या है।

iter + 5 

वह ऑपरेशन केवल यादृच्छिक अभिगम इटरेटर के लिए परिभाषित किया गया है।

std::next(iter, 5) 

हालांकि, यह ऑपरेशन आगे इटरेटर के लिए परिभाषित किया गया है, जो कि इटरेटर की एक विस्तृत श्रेणी है। संक्षेप में, std::next आपके कोड को अधिक सामान्यीकृत बनाता है।

cplusplus.com में विभिन्न इटरेटर प्रकारों द्वारा समर्थित ऑपरेटरों की पूरी सूची है, here उपलब्ध है। चूंकि उस पृष्ठ पर चार्ट दिखाता है, सभी यादृच्छिक अभिगम इटरेटर भी आगे हैं लेकिन लगभग सभी आगे इटेटरेटर यादृच्छिक पहुंच नहीं हैं। लिंक्ड सूचियों जैसी चीजें केवल std::next

+0

धन्यवाद! वही है जो मैं चाहता था। –

+3

बस थोड़ा जोड़ने के लिए, 'std :: next' "लागू' ++' 5 बार 'iter'' के लिए केवल एक कार्यान्वयन नहीं है, लेकिन यादृच्छिक पहुंच इटरेटर के साथ अधिक कुशल चीज़ करने के लिए पर्याप्त स्मार्ट है, और उपयोग फॉरवर्ड इटरेटर्स के लिए "धीमी" वृद्धि 5 गुना (जो केवल 5 पदों पर कूद नहीं सकती)। –

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