2010-06-10 20 views
15

यह आसान एक कंटेनर संबद्ध iterators प्राप्त करने के लिए दिया जाता है, उदाहरण है से कंटेनर के प्रकार:प्राप्त करें (अपने) सी में इटरेटर प्रकार ++ (एसटीएल)

std::vector<double>::iterator i; //An iterator to a std::vector<double> 

अगर यह संभव है मैं सोच रहा था, पुनरावर्तक प्रकार दिया , "संबंधित कंटेनर" के प्रकार को कम करने के लिए (यहां मैं मान रहा हूं कि प्रत्येक कंटेनर के लिए एक और केवल एक (गैर-कॉन्स) इटरेटर है)।

दरअसल, मैं एक टेम्पलेट metafunction कि (प्रत्येक एक कंटेनर के लिए मैन्युअल रूप से इसे विशेषज्ञ के बिना) सभी एसटीएल कंटेनर के साथ काम करता है ऐसा है कि चाहते हैं उदाहरण के लिए:

ContainerOf< std::vector<double>::iterator >::type 

std::vector<double> 
का मूल्यांकन

क्या यह संभव है? यदि नहीं, तो क्यों?

किसी भी मदद के लिए अग्रिम धन्यवाद!

+2

आप एक इटरेटर के concep बारे में पता लगाने की कोशिश कर रहे ? यानी अगर यह यादृच्छिक पहुंच है? एसटीएल इसके लिए टैग का उपयोग करता है। आमतौर पर यह जानने का कोई कारण नहीं है कि एक इटरेटर कहाँ से आता है। – pmr

+0

क्या आप आगे जानते हैं कि क्या आपके पास 7 एसटीएल कंटेनरों में से एक में इटरेटर है, या आपको "अन्य" खंड की भी आवश्यकता है? – MSalters

उत्तर

7

मुझे नहीं लगता कि यह संभव होगा। कुछ एसटीएल पुस्तकालयों पर आपके पास वास्तव में एक वेक्टर इटरेटर होता है जो सूचक सूचक के रूप में होता है, i.e. std::vector<T>::iterator is a T* इसलिए मैं उस तरह से कंटेनर प्रकार पर वापस आने के किसी भी तरीके से नहीं सोच सकता।

+0

हालांकि, यह किसी भी अन्य एसटीएल कंटेनर का पुनरावर्तक नहीं हो सकता है। केवल 7 हैं, और आप उन सभी को कम कर सकते हैं। – MSalters

+0

यह एक उचित बिंदु है। हालांकि मानचित्र और मल्टीमैप के बीच अंतर के बारे में कैसे? क्या आप उन्हें तुलना ऑपरेटर से अलग बता सकते हैं? – Hitobat

+0

यदि संरचना 'std :: iterator_traits ' haves 'typedef टी कंटेनर_ टाइप; 'हालांकि आप इस प्रकार के टाइपेड के साथ अपना स्वयं का' std :: iterator_traits_pro' बना सकते हैं, तो यह संभव हो सकता है। – k06a

0

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

+0

उत्तर के लिए धन्यवाद! अब मैं डर रहा हूं कि मेरी समस्या जानबूझकर "हल करने योग्य" नहीं है। – stepelu

0

इटरेटर का बिंदु यह है कि आप उन्हें अंतर्निहित कंटेनर प्रकार के बिना काम करने के लिए उपयोग करते हैं, उदाहरण के लिए एक प्रारंभ/अंत जोड़ी गुजरना और उस सीमा पर काम करना।

हालांकि, अगर आप सभी की देखभाल करते हैं तो यह इटेटरेटर प्रकार है, मेरा मानना ​​है कि अगर आप इटेटरेटर यादृच्छिक पहुंच है तो उदाहरण के लिए आप इटेटरेटर लक्षणों का उपयोग कर सकते हैं। std::advance लें, सामान्य मामला यह है कि यह इटरेटर एन बार पर operator++ पर कॉल करता है, लेकिन यादृच्छिक एक्सेस इटरेटर के लिए + = इसके बजाय उपयोग करने के लिए विशिष्ट है।

इसके अलावा मुझे कंटेनर प्रकार को इटरेटर से प्राप्त करने के किसी भी तरीके से अवगत नहीं है।

+0

टैग प्रेषण के माध्यम से पूरा किया जाता है। http://www.boost.org/community/generic_programming.html#tag_dispatching –

5

बस मस्ती के लिए, यहाँ कुछ मैं जल्दी से Boost.MPL साथ काट दिया है (चेतावनी: यह veeeery अल्पज्ञता का परीक्षण किया था, इसलिए सावधानी से कार्य):

#include <boost/mpl/list.hpp> 
#include <boost/mpl/find_if.hpp> 
#include <boost/type_traits.hpp> 
#include <vector> 
#include <string> 
#include <list> 
#include <set> 

// List of candidate container types 
template<typename T> 
struct ContainersOf : boost::mpl::list< 
    std::vector<T>, 
    std::basic_string<T>, 
    std::list<T>, 
    std::set<T> 
>{}; 

// Metafunction to evaluate if IteratorT == ContainerT::iterator 
template<class IteratorT, class ContainerT> 
struct IsIteratorOf 
{ 
    typedef typename 
    boost::is_same< 
     IteratorT, 
     typename ContainerT::iterator 
    >::type type; 
}; 

// Metafunction to compute a container type from an iterator type 
template<class IteratorT> 
struct ContainerOf 
{ 
    typedef typename 
    boost::mpl::deref<typename 
     boost::mpl::find_if< 
      ContainersOf<typename std::iterator_traits<IteratorT>::value_type>, 
      IsIteratorOf<IteratorT, boost::mpl::_1> 
     >::type 
    >::type type; 
}; 

// Test 
int main() 
{ 
    ContainerOf<std::list<int>::iterator>::type l; 
    std::list<int> l2 = l; // OK 
    std::vector<int> v = l; // Fails to compile 

    return 0; 
} 
+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद, हालांकि आपके समाधान के लिए कंटेनर प्रकारों को "विशेषज्ञता" की आवश्यकता है ContainerOf देखें। – stepelu

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