SORU
8 Kasım 2011, Salı


STL-tarzı yineleyici uygulamak ve ortak tuzaklar önlemek için?

Hangi STL-tarzı, rasgele erişim yineleyici bir sağlamak istiyorum bir koleksiyon yaptım. Bir örnek için bir yineleyici uygulama arama yaptım ama bulamadım. Sabit gerek [] * operatörlerin aşırı biliyorum. "STL-tarzı" ve önlemek için başka tuzaklar (varsa) nelerdir? bir yineleyici için neler gerekli

Bu kütüphane için çok gerekmedikçe üzerinde herhangi bir bağımlılık tanıtmak istemiyorum. ek içerik: Aynı derleyici (muhtemelen kıracak hiçbir STL) ile C 03 C ve 11 arasında ikili uyumluluk sağlamak için kendi koleksiyonumu yazıyorum.

CEVAP
8 Kasım 2011, Salı


http://www.cplusplus.com/reference/std/iterator/ C 11 standardının madde 24.2.2 ve görüşler ayrıntılar kullanışlı bir grafik var. Temelde, kullanımına geçerli işlemleri tanımlayan bir etiket ve etiketleri bir hiyerarşi var. Tamamen sembolik aşağıda, bu sınıflar aslında gibi diye bir şey yok.

iterator {
    iterator(const iterator&);
    ~iterator();
    iterator& operator=(const iterator&);
    iterator& operator  (); //prefix increment
    reference operator*() const;
    friend void swap(iterator& lhs, iterator& rhs); //C  11 I think
};
input_iterator : public virtual iterator {
    iterator operator  (int); //postfix increment
    value_type operator*() const;
    pointer operator->() const;
    friend bool operator==(const iterator&, const iterator&);
    friend bool operator!=(const iterator&, const iterator&); 
};
//once an input iterator has been dereferenced, it is 
//undefined to dereference one before that.
output_iterator : public virtual iterator {
    reference operator*() const;
    iterator operator  (int); //postfix increment
};
//dereferences may only be on the left side of an assignment
//once an input iterator has been dereferenced, it is 
//undefined to dereference one before that.
forward_iterator : input_iterator, output_iterator {
    forward_iterator();
};
//multiple passes allowed
bidirectional_iterator : forward_iterator {
    iterator& operator--(); //prefix increment
    iterator operator--(int); //postfix decrement
};

random_access_iterator : bidirectional_iterator {
    friend bool operator<(const iterator&, const iterator&);
    friend bool operator>(const iterator&, const iterator&);
    friend bool operator<=(const iterator&, const iterator&);
    friend bool operator>=(const iterator&, const iterator&);

    iterator& operator =(size_type);
    friend iterator operator (const iterator&, size_type);
    friend iterator operator (size_type, const iterator&);
    iterator& operator-=(size_type);  
    friend iterator operator-(const iterator&, size_type);
    friend difference_type operator-(iterator, iterator);

    reference operator[](size_type) const;
};

Ya std::iterator_traits<youriterator>, uzmanlaşmak ya da yineleyici aynı typedefs kendini koymak, veya std::iterator Bu typedefs) devralır. İkinci seçeneği tercih ediyorum, okunabilirlik için std ad ve bir şeyleri değiştirme önlemek için, ama çoğu kişi std::iterator devralır.

struct std::iterator_traits<youriterator> {        
    typedef ???? difference_type; //almost always ptrdif_t
    typedef ???? value_type; //almost always T
    typedef ???? reference; //almost always T& or const T&
    typedef ???? pointer; //almost always T* or const T*
    typedef ???? iterator_category;  //usually std::forward_iterator_tag or similar
};

Bu iterator_categorystd::input_iterator_tag, , *, *13std::output_iterator_tagstd::forward_iterator_tag, veya yineleyici karşılayan bağlı olarak std::random_access_iterator_tag biri olmalıdır. Senin yineleyici bağlı olarak, std::next, std::prev, std::advance, std::distance de uzmanlaşmak için seçebilirsiniz, ama bu nadiren gereklidir.son derece nadiristeyebilirsiniz davaları std::begin std::end uzmanım.

Konteyner iyisi de var const_iterator da (muhtemelen değişken) yineleyici sürekli veri benzer iterator dışında olmalı örtülü olarak constructable bir iterator ve kullanıcıların olması mümkün değiştirmek için veri. Sabit olmayan veri işaretçisi, iç işaretçi yaygındır, ve iterator kod tekrarını en aza indirmek için const_iterator miras var.

Writing your own STL Container yazımın yineleyici prototip/daha eksiksiz bir kap vardır.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • boogie2988

    boogie2988

    6 NİSAN 2006
  • Liberator

    Liberator

    14 EYLÜL 2007
  • mipd1980

    mipd1980

    25 EKİM 2006