C ++ virtual method that uses STL-style iterators

I want to have a ModelGenerator interface that has a generate () method that takes an iterable Evidence list and creates a model. Using the aliases of the STL pseudo-random interpretation iterator ...

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

But virtual functions cannot be templates. Therefore, I need to create a template for the whole class:

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

Ideally, what Id like to do is something like this ...

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

But there is no interface that the iterator inherits. (The std :: iterator class contains only a set of typedefs, without methods.)

The only way I can do this is to give the ModelGenerator the addEvidence () method, which adds them one after the other before calling generate (), but then I have to give the ModelGenerator state, which is a little painful.

How can I write a virtual method that accepts any STL container?

+6
source share
2 answers

It seems you need any_iterator . This is an iterator that does type erasure to isolate you from the actual implementation of the iterator.

Adobe has an implementation of any_iterator : http://stlab.adobe.com/classadobe_1_1any__iterator.html

Boost has any_range implementation: http://www.boost.org/doc/libs/1_49_0/libs/range/doc/html/range/reference/ranges/any_range.html

+5
source

For this purpose, you can use specialized specialization instead of virtual methods. From what I understand, you have a unique Evidence class, a number of different Model classes, and a desire to create a common factory to create the selected model from the Evidences sequence.

 #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); } 

You can use it as follows:

 int main() { std::vector<Evidence> v; Model1 m1 = make_model<Model1>(v.begin(), v.end()); Model2 m2 = make_model<Model2>(v.begin(), v.end()); } 
0
source

Source: https://habr.com/ru/post/916710/


All Articles