c++11 foreach syntax and custom iterator

前端 未结 4 1374
野性不改
野性不改 2020-12-23 16:07

I am writing an iterator for a container which is being used in place of a STL container. Currently the STL container is being used in many places with the c++11 foreach syn

相关标签:
4条回答
  • 2020-12-23 16:32

    You have two choices:

    • you provide member functions named begin and end that can be called like C.begin() and C.end();
    • otherwise, you provide free functions named begin and end that can be found using argument-dependent lookup, or in namespace std, and can be called like begin(C) and end(C).
    0 讨论(0)
  • 2020-12-23 16:33

    To my knowledge SomeSortedContainer just needs to provide begin() and end(). And these should return a standard compliant forward iterator, in your case SomeSortedContainerIterator, which would actually wrap a std::vector<Type>::iterator. With standard compliant I mean it has to provide the usual increment and dereferencing operators, but also all those value_type, reference_type, ... typedefs, which in turn are used by the foreach construct to determine the underlying type of the container elements. But you might just forward them from the std::vector<Type>::iterator.

    0 讨论(0)
  • 2020-12-23 16:52

    To be able to use range-based for, your class should provide const_iterator begin() const and const_iterator end() const members. You can also overload the global begin function, but having a member function is better in my opinion. iterator begin() and const_iterator cbegin() const are also recommended, but not required. If you simply want to iterate over a single internal container, that's REALLY easy:

    template< typename Type>
    class SomeSortedContainer{
    
        std::vector<Type> m_data; //we wish to iterate over this
        //container implementation code
    public:
        typedef typename std::vector<Type>::iterator iterator;
        typedef typename std::vector<Type>::const_iterator const_iterator;
    
        iterator begin() {return m_data.begin();}
        const_iterator begin() const {return m_data.begin();}
        const_iterator cbegin() const {return m_data.cbegin();}
        iterator end() {return m_data.end();}
        const_iterator end() const {return m_data.end();}
        const_iterator cend() const {return m_data.cend();}
    };    
    

    If you want to iterate over anything custom though, you'll probably have to design your own iterators as classes inside your container.

    class const_iterator : public std::iterator<random_access_iterator_tag, Type>{
        typename std::vector<Type>::iterator m_data;
        const_iterator(typename std::vector<Type>::iterator data) :m_data(data) {}
    public:
        const_iterator() :m_data() {}
        const_iterator(const const_iterator& rhs) :m_data(rhs.m_data) {}
         //const iterator implementation code
    };
    

    For more details on writing an iterator class, see my answer here.

    0 讨论(0)
  • 2020-12-23 16:52

    As others have stated, your container must implement begin() and end() functions (or have global or std:: functions that take instances of your container as parameters).

    Those functions must return the same type (usually container::iterator, but that is only a convention). The returned type must implement operator*, operator++, and operator!=.

    0 讨论(0)
提交回复
热议问题