2012-05-25 19 views
6

लेता है मैं एक इंटरफेस मॉडल जेनरेटर चाहता हूं जिसमें एक विधि उत्पन्न होती है() जो साक्ष्य की एक पुनरावृत्ति सूची लेती है और एक मॉडल बनाती है। एसटीएल छद्म बतख टाइपिंग इटरेटर मुहावरा का प्रयोग ...सी ++ वर्चुअल विधि जो एसटीएल-स्टाइल इटरेटर

template<class Model> 
class ModelGenerator { 
    public: 
    template<class Iterator> 
    virtual bool generate(Iterator begin, Iterator end, Model& model) = 0; 
}; 

लेकिन आभासी कार्यों टेम्प्लेट नहीं किया जा सकता। तो मैं पूरी कक्षा टेम्पलेट के लिए है:

template<class Model, class Iterator> 
class ModelGenerator { 
    public: 
    virtual bool generate(Iterator begin, Iterator end, Model& model) = 0; 
}; 

आदर्श रूप में मैं क्या करना चाहते हैं क्या कुछ इस तरह है ...

template<class Model, class Evidence> 
class ModelGenerator { 
    public: 
    virtual bool generate(iterator<Evidence>& begin, 
          iterator<Evidence>& end, 
          Model& model) = 0; 
}; 

लेकिन ऐसी कोई इंटरफ़ेस है कि iterators से विरासत है। (कक्षा std :: iterator में केवल typedefs का कोई गुच्छा नहीं है, कोई तरीका नहीं है।)

ऐसा करने का एकमात्र तरीका मैं मॉडल जेनरेटर को एक विधि addEvidence() देना चाहता हूं जो उत्पन्न करने से पहले उन्हें एक-एक करके जोड़ता है (), लेकिन फिर मुझे मॉडल जेनरेटर स्टेटस देना है जो दर्द का थोड़ा सा है।

मैं एक वर्चुअल विधि कैसे लिख सकता हूं जो कोई एसटीएल कंटेनर लेता है?

+1

CRTP यहाँ उपयोगी हो सकता है। – Mehrdad

+2

आपको वर्चुअल फ़ंक्शन से सभी इटरेटर ऑपरेशंस को फैक्टरिंग के बारे में सोचना चाहिए। टेम्पलेटेड फ़ंक्शन एक 'std :: वेक्टर <साक्ष्य *>' उत्पन्न कर सकता है और उसे 'वर्चुअल' फ़ंक्शन पर भेज सकता है। उस प्रकार के रैपर की प्रदर्शन लागत और प्रोग्रामिंग प्रयास 'any_iterator' /' any_range' से कम होने की संभावना है। – Potatoswatter

उत्तर

5

आपको any_iterator की आवश्यकता है। यह एक पुनरावर्तक है जो वास्तविक इटरेटर कार्यान्वयन से आपको अपनाने के लिए प्रकार मिटा देता है।

एडोब any_iterator के एक कार्यान्वयन है: http://www.boost.org/doc/libs/1_49_0/libs/range/doc/html/range/reference/ranges/any_range.html

+0

धन्यवाद! क्या आपको पता है कि किसी भी प्रमुख पुस्तकालय में कोई_इटरेटर पाया जाता है? –

+1

ध्यान रखें कि 'any_iterator' कार्यान्वयन धीमे हैं, इसलिए केवल तभी उपयोग करें जब आपको करना होगा। –

+0

@funkybluecoffee: दुर्भाग्य से बूस्ट नहीं। एडोब में एक है: http://stlab.adobe.com/classadobe_1_1any__iterator.html –

0

आप यह अंत करने के लिए आभासी तरीकों के बजाय टेम्पलेट विशेषज्ञता का उपयोग करने पर विचार कर सकते: http://stlab.adobe.com/classadobe_1_1any__iterator.html

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

#include <vector> 
#include <iostream> 

struct Model1 { }; 
struct Model2 { }; 
struct Evidence { }; 

template<class Model> 
struct ModelGenerator; 

template<> 
struct ModelGenerator<Model1> 
{ 
    typedef Model1 model_type; 

    template<class Iterator> 
    model_type generate(Iterator begin, Iterator end) 
    { 
     std::cout << "Generate Model1\n"; 
     return model_type(); 
    } 
}; 

template<> 
struct ModelGenerator<Model2> 
{ 
    typedef Model2 model_type; 

    template<class Iterator> 
    model_type generate(Iterator begin, Iterator end) 
    { 
     std::cout << "Generate Model2\n"; 
     return model_type(); 
    } 
}; 

template<class Model, class Iterator> 
Model make_model(Iterator begin, Iterator end) 
{ 
    ModelGenerator<Model> gen; 
    return gen.generate(begin, end); 
} 

आप इसे इस तरह से उपयोग कर सकते हैं:

int main() 
{ 
    std::vector<Evidence> v; 

    Model1 m1 = make_model<Model1>(v.begin(), v.end()); 
    Model2 m2 = make_model<Model2>(v.begin(), v.end()); 
}