2008-12-17 17 views
6

के मालिक को ढूंढना क्या कोई तरीका है कि मैं एक इटरेटर द्वारा इंगित कंटेनर पा सकता हूं? विशेष रूप से, मैं एक विशेष std :: vector :: iterator द्वारा इंगित std :: वेक्टर को खोजने में सक्षम होना चाहता हूं ताकि मैं वास्तव में उस वेक्टर के संदर्भों को पारित किए बिना सीमा की जांच कर सकूं।एक एसटीएल इटरेटर

अगर (जैसा कि मुझे संदेह है) तो जवाब नहीं है, क्यों नहीं?

संपादित करें: कई त्वरित और (बड़े पैमाने पर) सटीक उत्तरों के लिए धन्यवाद। Evan Teran इसे नाखून। मैं अनुकूलन के बारे में सोच नहीं रहा था, लेकिन अब यह स्पष्ट है।

कुछ लोगों ने पूछा कि मैं इसके लिए क्या करना चाहता हूं। यह बहुत महत्वपूर्ण नहीं है। मेरे पास एक ऑब्जेक्ट है जिसे वेक्टर में इंगित करने वाले वेक्टर और इटरेटर के साथ शुरू किया गया है। यह प्यारा और सुविधाजनक होगा अगर मैं ऑब्जेक्ट को केवल इटेटरेटर के साथ शुरू कर सकता हूं, क्योंकि तब मैं वेक्टर :: इटरेटर्स को सीधे इस ऑब्जेक्ट में परिवर्तित कर सकता हूं (यह अजीब लगता है लेकिन विशेष मामले में समझ में आता है)। लेकिन यह बिल्कुल महत्वपूर्ण नहीं है।

उत्तर

6

मुझे विश्वास नहीं है। अगर इटरेटर्स को मालिक के लिए एक संदर्भ/सूचक रखना पड़ा, तो उनके लिए एक हल्के वजन सूचक को अनुकूलित करना असंभव होगा (जो वेक्टरों और ऐसे जैसे संगत भंडारण की गारंटी वाले कंटेनरों के साथ किया जा सकता है)।

0

मुझे विश्वास नहीं है कि ऐसा करने के लिए एक खुला तरीका है। कारण यह है कि यह इटरेटर का उद्देश्य नहीं है। निश्चित रूप से, कोई तकनीकी कारण नहीं है कि एक इटेटरेटर अपने मूल कंटेनर को पॉइंटर नहीं रख सका। भले ही इसे इस तरह कार्यान्वित किया गया हो कि उस सूचक की आवश्यकता नहीं है, फिर भी यह इसे पकड़ सकता है।

Iterators का संग्रह संग्रह पर पुन: प्रयास करना है, और इस तरह, वे ऐसा करने के लिए आवश्यक इंटरफ़ेस प्रदान करते हैं और केवल यही। यह अच्छा ऑब्जेक्ट उन्मुख प्रोग्रामिंग सिद्धांत है।

क्या मैं पूछ सकता हूं कि आपका उपयोग-मामला क्या है, आपको एक इटरेटर के साथ कंटेनर की "रेंज" जानने की आवश्यकता है?

3

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

#include <algorithm> 
#include <cstdio> 
#include <cstring> 

int 
main(int argc, char *argv[]) 
{ 
     const char s[] = "Hello, world!"; 
     const char *begin = s; 
     const char *end = s + strlen(s); 

     std::for_each(begin, end, putchar); 

     return 0; 
} 

कैसे आप एक सूचक से मूल स्ट्रिंग को पुनः प्राप्त कर सकता है (अगर यह स्ट्रिंग की शुरुआत में बताया नहीं है)?

हालांकि, अगर आपको इस कार्यक्षमता की आवश्यकता है तो आप हमेशा implement इटरेटर के आस-पास अपना स्वयं का रैपर कर सकते हैं जो कंटेनर के संदर्भ को संग्रहीत करता है।

+0

मुझे नहीं लगता कि वास्तव में इस सवाल के साथ कुछ भी करने के लिए कुछ भी है ... – jdmichal

+3

यह दर्शाता है कि आप एक ठोस और सरल उदाहरण के साथ एक पुनरावृत्ति से कंटेनर क्यों नहीं प्राप्त कर सकते हैं ... –

2

सिद्धांत रूप में एक तरीका है यदि प्रश्न में पुनरावर्तक कम से कम एक अग्रेषणकर्ता है। आप प्रत्येक उम्मीदवार कंटेनर के लिए यह जांच सकते हैं कि आपका इटरेटर [पहले, आखिरी) में इटरेटर में से एक है या नहीं। चूंकि आप एक वेक्टर कंटेनर का उपयोग कर रहे हैं, तो आपके पास एक यादृच्छिक एक्सेस इटेटरेटर है, आप इस चेक को जल्दी से करने के लिए ऑपरेटर से कम उपयोग कर सकते हैं।

आपको सभी उम्मीदवार वैक्टरों को जानना होगा जिनके खिलाफ फ्रंट, की जांच करना है और यह कंटेनर प्राप्त करने का एक सामान्य तरीका नहीं है जिसके लिए एक इटरेटर संबंधित है।

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

+1

यह पहला सुझाव निश्चित रूप से अस्थिर कार्यान्वयन विवरण पर निर्भर है, और बनाए रखने के लिए बहुत ही हैकिश होगा। मैं सजावटी को बहुत अधिक लागू करूंगा; कम से कम तब यह हमेशा काम करने की गारंटी देता है और मेरे इरादे स्पष्ट करता है। – jdmichal

+0

गलत। पहला सुझाव या तो क्षमता समानता जांचकर्ताओं पर निर्भर करता है, जो आधिकारिक रूप से समर्थित है, या आधिकारिक रूप से समर्थित है, जो यादृच्छिक-पहुंच iterators की जांच करने की क्षमता है। एक हैक नहीं मिला। कृपया स्टडोक पढ़ें। –

+0

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

1

एसटीएल इसके लिए अनुमति नहीं देता है।

उदाहरण के लिए, वेक्टर इटरेटर्स को केवल एक सूचक के रूप में लागू किया जा सकता है। और ऑब्जेक्ट आवंटित किए गए कुछ डेटा को इंगित करने वाले पॉइंटर से किसी ऑब्जेक्ट को पुनर्प्राप्त करने का कोई सामान्य तरीका नहीं है।

0

जैसा कि पहले सुझाव दिया गया था कि आपके कोड को फिर से लिखना सर्वोत्तम है ताकि आपको इस व्यवहार की आवश्यकता न हो। यह एक सिक्का धारण करने जैसा ही है, लेकिन आपको पता नहीं है कि यह तब तक आता है जब तक कि आपने पेपर पर ध्यान न दिया हो।

यदि आप कोड को फिर से लिखने में असमर्थ हैं तो भी आप एक रैपिंग ऑब्जेक्ट पेश कर सकते हैं जिसमें कंटेनर और इटरेटर के लिए पॉइंटर शामिल हो। विशेष रूप से आपको इसकी क्या आवश्यकता है?

4

उस काम को करने का कोई तरीका नहीं है। कारण सरल है: कंटेनर को इंगित करने के लिए इटरेटर को एक रास्ता जोड़ना

  • प्वाइंटलेस। Iterators एक संग्रह पर फिर से शुरू होता है। जैसा कि दूसरे ने कहा, केवल इतना, और कुछ नहीं।
  • पुनरावर्तक आवश्यकताओं के साथ संगत नहीं है। याद रखें कि एक सूचक एक यादृच्छिक अभिगम इटरेटर है। इटरेटर में एक कंटेनर पॉइंटर डालने से एल्गोरिदम के लिए कोई उपयोग नहीं किया जाएगा, क्योंकि वे सामान्य इटरेटर कार्यान्वयन से सामान्य, सामान्य होने का इरादा रखते हैं। एक इटरेटर के रूप में उपयोग किए जाने वाले पॉइंटर के पास एक सदस्य के रूप में ली गई सरणी में एक सूचक नहीं हो सकता है।

आप कहते हैं कि आपको रेंज जांच के लिए इसकी आवश्यकता है। आप एक अंत इटरेटर प्रदान कर सकते हैं जो एक सीमा की अंतिम मान्य इटरेटर स्थिति के बाद एक को इंगित करता है। जांचें कि आपकी वर्तमान स्थिति अंत में नहीं है या नहीं। रेंज जांच के लिए आपको बस इतना करना है।

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