2016-12-25 6 views
0

私はテンプレートクラスLinkedListとTraversibleを作成する必要があります。 Class 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のテンプレートは、2つのパラメータを持っており、それが1つしかないはずです。 これは私がやるべきことですか?私はテンプレートとイテレータには新しいことを覚えておいてください。

+0

なぜTraversibleテンプレートには1つのパラメータが必要ですか? –

+0

このアサイメントでは、Traversableクラスを書く必要があると言います。 Nebeski

答えて

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