2010-01-31 17 views
5

मैं लिख रहा हूं (एक आत्म-शिक्षण अभ्यास के रूप में) एक साधारण एसटीएल-जैसी रेंज। यह एक अपरिवर्तनीय-रैंडम-एक्सेस "कंटेनर" है।एसटीएल-लाइक रेंज, अगर मैंने ऐसा किया तो क्या गलत हो सकता है?

struct range 
{ 
... 
private: 
    value_type m_first_element, m_element_count, m_step; 
}; 

क्योंकि मेरी सीमा तत्व पकड़ नहीं है, यह वांछित तत्व की गणना करता है: मेरी सीमा है, केवल अपनी शुरुआत तत्व, तत्वों की संख्या और कदम आकार (लगातार दो तत्वों के बीच अंतर) रहता है का उपयोग करते हुए निम्नलिखित:

// In the standards, the operator[] 
// should return a const reference. 
// Because Range doesn't store its elements 
// internally, we return a copy of the value. 
value_type operator[](size_type index) 
{ 
    return m_first_element + m_step*index; 
} 

आप देख सकते हैं, मैं एक const reference वापस नहीं कर रहा हूँ के रूप में मानकों का कहना है। अब, क्या मुझे लगता है कि मानक पुस्तकालय में गैर-उत्परिवर्तनीय एल्गोरिदम का उपयोग करने के मामले में const reference और तत्व की एक प्रति समान है?

विषय के बारे में कोई सलाह बहुत सराहना की है।


@ स्टेव जेसॉप: अच्छा बिंदु कि आपने इटरेटर का उल्लेख किया है।

असल में, मैंने sgi as my reference का उपयोग किया। उस पृष्ठ के अंत में, यह कहते हैं:

मान लिया जाये x और y एक ही श्रेणी से iterators हैं:

Invariants पहचान
x == y if and only if &*x == &*y

इसलिए, यह फोड़े उसी मूल प्रश्न के नीचे मैंने वास्तव में पूछा है :)

+0

यदि आपने ऑपरेटर में वापस जाने के लिए कोई तत्व बनाया है [] तो उसके संदर्भ में वापस आ गया है, क्या यह संदर्भ हमेशा खराब संदर्भ नहीं होगा, क्योंकि उदाहरण तुरंत दायरे से बाहर हो जाएगा?
कंटेनर में संदर्भों के बारे में मानक वार्ता, जो एक कंटेनर नहीं है। –

+0

@ क्रिस मैं सहमत हूं कि यह वास्तविक कंटेनर नहीं है। मैं अपने दूसरे वाक्य में डबल कोट्स के बीच "कंटेनर" क्यों डालता हूं। – AraK

+0

आप प्रेरणा के लिए boost :: iterator_range और boost :: sub_range को देखना चाह सकते हैं: http://www.boost.org/doc/libs/1_41_0/libs/range/index.html –

उत्तर

1

मानक एल्गोरिदम वास्तव में operator[] का उपयोग नहीं करते हैं, वे सभी इसे पुनरावर्तकों के संदर्भ में परिभाषित नहीं किए जाते हैं जब तक कि मैं कुछ महत्वपूर्ण भूल नहीं जाता। क्या operator[] के शीर्ष पर मानक एल्गोरिदम को फिर से लागू करने की योजना है, जो आपके "श्रेणियों" के बजाय इटरेटर के बजाय है?

जहां गैर-उत्परिवर्तित एल्गोरिदम इटरेटर्स का उपयोग करते हैं, वे सभी को *it के संदर्भ में परिभाषित किया जा रहा है जिसे किसी भी निर्दिष्ट ऑपरेशन या फ़ंक्शन कॉल के लिए असाइन करने योग्य या अन्यथा मान्य किया जा सकता है। मुझे लगता है कि सभी या अधिकतर ऐसे ओप एक मूल्य के साथ ठीक हैं।

एक बात जो मैं सोच सकता हूं, यह है कि आप उस मूल्य को पार नहीं कर सकते जहां गैर-कॉन्स्ट संदर्भ की अपेक्षा की जाती है। क्या कोई गैर-उत्परिवर्तनीय एल्गोरिदम है जिसके लिए गैर-कॉन्स्ट संदर्भ की आवश्यकता है? शायद नहीं, बशर्ते कि किसी भी मज़ेदार पैरामीटर इत्यादि में const पर्याप्त हों।

तो क्षमा करें, मैं निश्चित रूप से यह नहीं कह सकता कि कोई अजीब कोनों में गलत नहीं है, लेकिन यह मूल रूप से मेरे लिए ठीक लगता है।यहां तक ​​कि यदि कोई निगल्स हैं, तो आप एल्गोरिदम और मानक वाले संस्करणों के बीच आवश्यकताओं में बहुत मामूली अंतर के साथ उन्हें ठीक करने में सक्षम हो सकते हैं।

संपादित करें: दूसरी बात जो गलत हो सकती है वह पॉइंटर्स/संदर्भ ले रही है और उन्हें बहुत लंबा रख रही है। जहां तक ​​मुझे याद है, मानक एल्गोरिदम तत्वों के लिए पॉइंटर्स या संदर्भ नहीं रखते हैं - इसका कारण यह है कि यह कंटेनर है जो तत्वों के पॉइंटर्स की वैधता की गारंटी देता है, इटरेटर प्रकार केवल आपको बताते हैं कि इटरेटर मान्य रहता है (उदाहरण के लिए एक इनपुट इटरेटर की एक प्रति मूल रूप से बढ़ी जाने पर मान्य नहीं रहती है, जबकि आगे इटरेटर्स को बहु-पास एल्गोरिदम के लिए इस तरह कॉपी किया जा सकता है)। चूंकि एल्गोरिदम कंटेनरों को नहीं देखते हैं, केवल इटरेटर, उनके पास कोई कारण नहीं है कि मैं यह मानने के बारे में सोच सकता हूं कि तत्व लगातार हैं।

1

एस में आइटम टीएल कंटेनरों को हर समय प्रतिलिपि बनाने की उम्मीद है; उदाहरण के लिए, एक वेक्टर को फिर से आवंटित करने के बारे में सोचें। तो, आपका उदाहरण ठीक है, सिवाय इसके कि यह केवल यादृच्छिक iterators के साथ काम करता है। लेकिन मुझे संदेह है कि उत्तरार्द्ध शायद डिजाइन द्वारा है। :- पी

1

क्या आप चाहते हैं कि आपकी सीमा एसटीएल एल्गोरिदम में प्रयोग योग्य हो? क्या यह पहले और आखिरी तत्वों से बेहतर नहीं होगा? (इस तथ्य को ध्यान में रखते हुए कि end() आवश्यक/उपयोग किया गया है, आपको इसे प्रदर्शन के लिए पूर्व-गणना करना होगा।) या, क्या आप संगत तत्वों पर निर्भर हैं (जो मेरा दूसरा बिंदु है)?

+0

'एंड()' की गणना बहुत आसानी से की जा सकती है: 'm_first_element + m_step * m_element_count', इसलिए यह वास्तव में कोई समस्या नहीं है। मैंने प्रश्न में जो कहा है उसे छोड़कर 'रेंज' एक * अपरिवर्तनीय * यादृच्छिक-पहुंच कंटेनर बनाने के लिए सब कुछ लिखा है :) – AraK

+0

यह मेरे प्रश्न का दूसरा हिस्सा था: क्या यह मानदंड स्मृति प्रबंधन भाग पर लगा देना ठीक है कंटेनर का? – dirkgently

+0

क्षमा करें, मुझे वह नहीं मिला जो आप कह रहे हैं, क्या आप और विस्तार कर सकते हैं :) – AraK

1

चूंकि आप "उद्धरण" में "कंटेनर" डालते हैं, आप जो भी चाहें कर सकते हैं।

एसटीएल प्रकार की चीजें (इटरेटर, कंटेनर पर विभिन्न सदस्य कार्य ..) संदर्भ संदर्भ दें क्योंकि संदर्भ अंतराल हैं, और कुछ संरचनाएं (यानी, myvec [i] = otherthing) तब संकलित कर सकती हैं। ऑपरेटर [] पर std :: मानचित्र पर सोचें। कॉन्स संदर्भों के लिए, प्रतिलिपि से बचने के लिए यह एक मूल्य नहीं है, मुझे लगता है।

हालांकि, जब भी सुविधाजनक हो, इस नियम का उल्लंघन हर समय किया जाता है। यह भी सामान्य है कि इटरेटर कक्षाएं एक संदर्भ चर या संदर्भ संदर्भ के उद्देश्य के लिए पूरी तरह से सदस्य चर में मौजूदा मान को संग्रहीत करती हैं (हां, यह संदर्भ अमान्य होगा यदि इटरेटर उन्नत है)।

यदि आप इस तरह की चीजों में रुचि रखते हैं तो आपको बूस्ट इटरेटर लाइब्रेरी की जांच करनी चाहिए।

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

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