声明迭代函数的接口

时间:2016-12-25 21:50:43

标签: c++ templates interface iterator

我有一个分配,我需要在其中创建模板类LinkedList和Traversible。类Traversible需要是一个接口,它声明了一些集合类的索引和迭代函数。我不知道如何为迭代器创建一个接口,所以LinkedList可以使用它。我在想像

template <class T, class U>
class ITraversible {
public:
    virtual U begin() noexcept = 0;
    virtual U end() noexcept = 0;
    virtual T& operator[](int) = 0;
};

然后在LinkedList头文件中我会这样做:

template <class T>
class LinkedList : public ITraversible<T,typename LinkedList<T>::iterator> {
    struct node {
        T data;
        node* next, *prev;
        explicit node(const T&);
        void connect(node*);
    };

    node *head, *tail;
    int n;

public:
    /*************************ITERATOR************************/
    class iterator : public std::iterator<std::bidirectional_iterator_tag, node*> {
        typename LinkedList<T>::node* itr;
        explicit iterator(node*) noexcept;
        friend class LinkedList;
    public:
        iterator& operator++();
        iterator operator++(int);
        iterator& operator--();
        iterator operator--(int);
        bool operator==(const iterator&) const noexcept;
        bool operator!=(const iterator&) const noexcept;
        T& operator*() const noexcept;
        T& operator->() const noexcept;
    };
    /**********************************************************/

    LinkedList() noexcept;
    LinkedList(std::initializer_list<T>);
    LinkedList(const LinkedList&);
    LinkedList(LinkedList&&) noexcept;
    ~LinkedList() noexcept;
    LinkedList& operator=(LinkedList) noexcept;

    template <class A>
    friend void swap(LinkedList<A>&, LinkedList<A>&);

    void add(const T&);
    void removeAt(int);
    int size() const noexcept;
    bool operator==(const LinkedList&) const noexcept;
    bool operator!=(const LinkedList&) const noexcept;
    virtual T& operator[](int) override;
    virtual iterator begin() noexcept override;
    virtual iterator end() noexcept override;
};

但是Traversable模板有两个参数,它应该只有一个。 这是我应该做的吗?请记住,我是模板和迭代器的新手。

1 个答案:

答案 0 :(得分:0)

创建界面时,您需要确定返回内容的静态类型。这些可能表现为动态不同,但在返回指针或引用时,除了使用子类型关系之外,不能更改类型。

就我个人而言,我认为这个练习对于C ++上下文来说是不明智的。使用Java或C#时可能有一定意义。但是,可以获得类似的行为 。一个反对的草图将是这样的(虽然这应该工作,它会相当慢):

template <typename T>
struct iterator_base {
     virtual iterator_base() {}
     virtual iterator_base<T>* do_clone() = 0;
     virtual T&                do_value() = 0;
     virtual void              do_next()  = 0;
     virtual bool              do_equal() = 0;
     // other operations to implement operator--, operator[], ...
};
template <typename It>
class iterator: iterator_base<typename std::iterator_traits<It>::value_type> {
    typedef typename std::iterator_traits<It>::value_type> type;
    It it;
    iterator_base<type>* do_clone() { return new iterator<It>(*this); }
    type& do_value() { return *this->it; }
    void  do_next()  { ++this->it; }
    bool  do_equal(iterator_base<type>* other) {
        return this->it == static_cast<iterator<It>>(other)->it;
    }
};

template <typename T>
class poly_iterator {
    std::unique_ptr<iterator_base<T>> ptr;
public:
     poly_iterator(iterator_base<T>* ptr): ptr(ptr) {}
     poly_iterator(poly_iterator const& other): ptr(other.ptr->clone()) {}
     poly_iterator& operator= (poly_iterator other) {
         other.swap(this);
         return *this;
     }
     void swap(poly_iterator& other) { swap(this->ptr, other.ptr); }
     T& operator*() { return this->ptr->value(); }
     T* operator->() { return &this->operator*(); }
     poly_iterator& operator++() { this->ptr->next(); return *this; }
     poly_iterator  operator++(int) {
         poly_iterator rc(*this);
         this->operator++();
         return rc;
     }
     bool operator== (poly_iterator const& other) {
         return this->ptr->equal(other.ptr.ptr());
     }
     bool operator!= (poly_iterator const& other) {
         return !(*this == other);
     }
     // other operations
};
// define a suitable specialization of std::iterator_traits<poly_iterator<T>>

template <typename T>
class ITraversible {
    virtual iterator_base<T>* do_begin() = 0;
    virutal iterator_base<T>* do_end()   = 0;

public:
    poly_iterator<T> begin() { return this->do_begin(); }
    poly_iterator<T> end()   { return this->do_end(); }
    // other operations
};

template <typename T>
class List: public ITraversible<T> {
    std::list<T> list;

    iterator_base<T>* do_begin() {
        return iterator<std::list<T>::iterator>(list.begin());
    }
    iterator_base<T>* do_end() {
        return iterator<std::list<T>::iterator>(list.end());
    }
public:
    // whatever is needed to fill the list
};