简体   繁体   English

迭代器继承和继承 *this

[英]Iterator Inheritance and inheriting *this

How to write a base class and several derived classes of iterator?迭代器的一个基类和几个派生类怎么写?

Does the iterator have to return itself (*this)?迭代器是否必须返回自身(*this)?

So far, I use typename X and static_cast<X&>(*this) to allow the derived class to inherit a function that return itself from the base class.到目前为止,我使用typename Xstatic_cast<X&>(*this)来允许派生类继承一个从基类返回自身的函数。

This looks ugly. This看起来很丑。 Is there a better way?有没有更好的办法?

Simplified Code:简化代码:

#include <iterator>
#include <iostream>
template <typename T, typename X>
class BaseIterator : public std::iterator<std::input_iterator_tag, T> {
    //Not intended to be used directly.
    private:
        T* p;
    protected:
        virtual void increment(void)=0;
        virtual T* stride_index(int index)=0;
    public:
        virtual ~BaseIterator(){} //virtual destructor.
        X operator++(int) { //takes a dummy int argument
            X tmp(static_cast<X&>(*this) );
            increment();
            return tmp;
        }
        bool operator==(const X & rhs) { return p==rhs.p; }
} ;
template <typename T>
class ContiguousIterator : public BaseIterator<T, ContiguousIterator<T> > {
    private:
        T* p;
    protected:
        inline void increment(void) {++p;}
        inline T* stride_index(int index){return p + index;}
    public:
        virtual ~ContiguousIterator(){} //destructor.
        ContiguousIterator(T* x) :p(x) {}
        ContiguousIterator(const ContiguousIterator<T> & mit) : p(mit.p) {}
} ;

int main(void){
    int i[]={0,1,2,3,4,5};
    ContiguousIterator<int> itbegin(i);
    ContiguousIterator<int> it(i);
    it++;
    std::cout << "result: " << (it == itbegin) << std::endl;
}

The alternative is to forget about using inheritance to write less code.另一种方法是忘记使用继承来编写更少的代码。 Just copy and paste the function that return *this to the derived classes.只需将返回*this的函数复制并粘贴到派生类即可。

That alternative seems increasingly acceptable to me ...这种选择似乎越来越为我所接受......

Generally, virtual is a lot of overhead for something like iterators which ought to be lightweight.一般来说,对于应该是轻量级的迭代器之类的东西来说, virtual是很多开销。 The usual way to go is CRTP.通常的方法是CRTP。 Which is a little tricky, but looks like this:这有点棘手,但看起来像这样:

template <typename T, typename X>
class BaseIterator : public std::iterator<std::input_iterator_tag, T> {
    protected:
        T* p;
        X* self() {return static_cast<X*>(this);}
        const X* self() const {return static_cast<const X*>(this);}
        BaseIterator(T* x) :p(x) {}
    public:
        X operator++(int) { //takes a dummy int argument
            X tmp(*self());
            self()->increment();
            return tmp;
        }
        bool operator==(const X & rhs) const { return p==rhs.p; }
} ;

The base usually takes the derived type, plus whatever it needs for function signatures as template parameters.基类通常采用派生类型,加上函数签名所需的任何内容作为模板参数。 Then you add two self() functions, which give you the derived type, which means you don't actually need virtual .然后添加两个self()函数,它们为您提供派生类型,这意味着您实际上并不需要virtual Everything is trivially inlined by the compiler.一切都由编译器简单地内联。 (Note I've also given it a sane constructor, and made operator== const . (注意我还给了它一个健全的构造函数,并制作了operator== const

template <typename T>
class ContiguousIterator : public BaseIterator<T, ContiguousIterator<T> > {
    public:
        typedef BaseIterator<T, ContiguousIterator<T> > parent;
        void increment(void) {++(this->p);}
        T* stride_index(int index) const {return this->p + index;}
    public:
        virtual ~ContiguousIterator(){} //destructor.
        ContiguousIterator(T* x) :parent(x) {}
        ContiguousIterator(const ContiguousIterator<T> & mit) : parent(mit.p) {}
} ;

Then the derived type simply inherits as normal, except you have to use this-> to access the member, since the parent is a template.然后派生类型只是照常继承,除非您必须使用this->来访问成员,因为父类型是模板。 See it working here: http://coliru.stacked-crooked.com/a/81182d994c7edea7看到它在这里工作: http : //coliru.stacked-crooked.com/a/81182d994c7edea7

This produces a highly efficient iterator, with no overhead.这会产生一个高效的迭代器,没有开销。 I believe this technique is used quite heavily in Boost's iterator library: http://www.boost.org/doc/libs/1_59_0/libs/iterator/doc/#new-style-iterators我相信这种技术在 Boost 的迭代器库中被大量使用: http : //www.boost.org/doc/libs/1_59_0/libs/iterator/doc/#new-style-iterators

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM