2012-11-13 22 views
16

दिए गए कंटेनर की तुलना फ़ंक्शन को पुनर्प्राप्त करें, एक पुनरावर्तक को देखते हुए, क्या यह इटरेटर इस संग्रह के लिए सही तुलना फ़ंक्शन को पुनर्प्राप्त/उपयोग करना संभव है?एक इटरेटर

उदाहरण के लिए, मैं एक सामान्य एल्गोरिथ्म लिख रहा हूँ मान लें:

template <class InIt, class T> 
void do_something(InIt b, InIt e, T v) { 
    // ... 
} 

अब मान लें कि मैं, कुछ सरल करने के लिए [b..e) में v लगता है की तरह चाहते हैं। यदि b और estd::vector पर इटरेटर हैं, तो मैं बस if (*b == v) ... का उपयोग कर सकता हूं। आइए मान लें कि b और estd::map पर इटरेटर हैं। इस मामले में, I केवल कुंजी की तुलना करें, मानचित्र में जो कुछ भी शामिल है उसका पूरा मूल्य प्रकार नहीं।

तो सवाल यह है कि, उन इटरेटर को मानचित्र में दिया गया है, मैं उस मानचित्र की तुलना फ़ंक्शन को कैसे प्राप्त करूं जो केवल चाबियों की तुलना करेगा? साथ ही, मैं अंधेरे से यह नहीं मानना ​​चाहता कि मैं map के साथ काम कर रहा हूं। उदाहरण के लिए, यदि इटरेटर ने set पर इंगित किया है, तो मैं set के लिए परिभाषित तुलना फ़ंक्शन का उपयोग करना चाहता हूं। अगर उन्होंने vector या deque पर इंगित किया है, तो मुझे शायद == का उपयोग करना होगा, क्योंकि उन कंटेनरों में एक तुलनात्मक कार्य परिभाषित नहीं होगा।

ओह, लगभग भूल गया: मुझे लगता है कि कई मामलों में, एक कंटेनर केवल तत्व उसमें शामिल के लिए operator< बजाय operator== के समतुल्य होगा - मुझे लगता है कि उपयोग करने में सक्षम होने के साथ पूरी तरह से ठीक हूँ।

+0

अभी कोई जवाब लिखने का कोई समय नहीं है, लेकिन इससे http://en.cppreference.com/w/cpp/container/map/key_comp मदद मिल सकती है। हम्म, ज्यादा नहीं, हालांकि। मुश्किल हिस्सा कंटेनर प्राप्त कर रहा है। –

+0

मैं आपके 'सेट' मामले के लिए उलझन में हूं। 'सेट' के तुलनित्र को कुल-आदेश होना आवश्यक है, जो 'ऑपरेटर ==' के मामले में नहीं है। – pmr

+0

क्या यह वही नहीं है, भले ही आप केवल नक्शा प्रविष्टि की कुंजी या पूरी प्रविष्टि की तुलना करें? [संपादित करें] कभी भी ध्यान न दें, बेशक यह नहीं है - आपके पास मैप किए गए हिस्से पर समानता संचालन नहीं हो सकता है। –

उत्तर

6

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

उदाहरण के लिए, यदि आप एक metafunction निर्धारित करने के लिए * VALUE_TYPE * std::pair<const K, T> है, जो एक संकेत है कि यह एक std::map हो सकता है कि और प्रकार K और T निकालने के बाद कोशिश का उपयोग कर सकते हैं कि प्रकार का निर्धारण करने के लिए एक metafunction उपयोग करने के लिए X, Y के एक विशेष संयोजन के लिए इटरेटर और std::map<K,T,X,Y>::iterator या std::map<K,T,X,Y>::const_iterator मिलान का प्रकार।

मानचित्र के मामले कि करने के लिए पर्याप्त हो सकता है यह निर्धारित में (यानी सफलता की प्रबल संभावना के साथ लगता है) कि इटरेटर एक std::map को संदर्भित करता है, पर आप को ध्यान देना चाहिए, भले ही आप का उपयोग कर सकते हैं और यहां तक ​​कि निकालने तुलनात्मक के प्रकार X, जो के लिए पर्याप्त नहीं है सामान्य मामले में तुलनित्र को दोहराएं। जबकि असामान्य (और अनुशंसित नहीं) तुलनित्रों के पास राज्य हो सकता है, और आप यह नहीं जान पाएंगे कि कंटेनर तक पहुंच के बिना तुलनित्र की विशेष स्थिति कौन सी है।यह भी ध्यान रखें कि ऐसे मामले हैं जहां std::vector<> के कुछ कार्यान्वयन में इस प्रकार की ह्युरिस्टिक भी मदद नहीं करेगा, इटरेटर प्रकार सीधे एक सूचक है, और उस स्थिति में आप एक 'पुनरावर्तक' के बीच एक सरणी और एक पुनरावर्तक के बीच std::vector<> में अंतर नहीं कर सकते एक ही अंतर्निहित प्रकार के।

11

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

+2

उदाहरण: कुछ 'स्ट्रिंग' और 'वेक्टर' में इटरेटर को नंगे पॉइंटर्स के रूप में कार्यान्वित किया गया था (अनुक्रमिक और संगत अंतर्निहित बफर का लाभ लेना)। –

+0

भले ही आप कंटेनरों को तर्क के रूप में लेते हैं, फिर भी आपको 'एसोसिएटिव कोंटेनर' से 'अनुक्रम' को अलग करने के लिए चाल पर भरोसा करना होगा। मुझे लगता है कि 'is_associative_container' लिखना मुश्किल है जो विश्वसनीय रूप से काम करता है। – pmr

+0

@pmr: यह विशेषता वास्तव में सरल है यदि आप केवल मानक कंटेनरों का समर्थन करना चाहते हैं ... आपको बस यह निर्धारित करने की आवश्यकता है कि यह प्रकार 'std :: map',' std :: multimap', 'std :: set में से एक है या नहीं ',' std :: multiset' (और अनियंत्रित संस्करण यदि आपको उनको समर्थन करने की आवश्यकता है, हालांकि * तुलनित्र * की अवधारणा उस स्पष्ट नहीं है) –

3

दुर्भाग्यवश इटरेटर हमेशा उस कंटेनर के बारे में नहीं जानते हैं जिसमें उन्हें शामिल किया जाता है (और कभी-कभी वे मानक कंटेनर में नहीं होते हैं)। यहां तक ​​कि iterator_traits में केवल value_type के बारे में जानकारी है जो आपको विशेष रूप से बताती है कि तुलना कैसे करें।

इसके बजाय, मानक पुस्तकालय से प्रेरणा आकर्षित करते हैं। सभी सहयोगी कंटेनर (map, आदि) std::find का उपयोग करने के बजाय अपने स्वयं के find विधियां हैं। और यदि आप को ऐसे कंटेनर पर std::find का उपयोग करने की आवश्यकता है, तो आप नहीं करते: आप find_if का उपयोग करते हैं।

ऐसा लगता है कि आपके समाधान यह है कि सहयोगी कंटेनरों के लिए आपको do_something_if की आवश्यकता है जो यह बताता है कि प्रविष्टियों की तुलना कैसे करें।

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