首页 文章

采用STL样式迭代器的C虚方法

提问于
浏览
6

我想要一个接口ModelGenerator,它有一个方法generate(),它接受一个可迭代的Evidence列表并创建一个Model . 使用STL伪鸭子类型迭代器成语...

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

但是虚函数不能模板化 . 所以我必须模拟整个 class :

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

但迭代器没有继承这样的接口 . (类std :: iterator只包含一堆typedef,没有方法 . )

我能想到的唯一方法是给ModelGenerator一个方法addEvidence(),它在调用generate()之前逐个添加它们,但是我必须给出一个有点痛苦的ModelGenerator状态 .

如何编写一个带有任何STL容器的虚方法?

2 回答

  • 0

    你似乎需要 any_iterator . 这是一个迭代器,它执行类型擦除以使您与实际的迭代器实现绝缘 .

    Adobe有一个 any_iterator 的实现:http://stlab.adobe.com/classadobe_1_1any__iterator.html

    Boost实现了 any_rangehttp://www.boost.org/doc/libs/1_49_0/libs/range/doc/html/range/reference/ranges/any_range.html

  • 5

    您可以考虑使用模板专门化而不是虚拟方法 . 根据我的理解,您有一个独特的Evidence类,一些不同的Model类,并且需要创建一个通用工厂来从一系列证据中生成一个选定的模型 .

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

相关问题