Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I define iterator and const_iterator in my class while I uses std::vector as field in my class?

Given the following class:

template<class T>
class A {
    vector<T> arr;
public:
    A(int size);
    A(vector<T> arr);
    int size() const;
    A& operator=(const A& p);

    template<class S>
    friend ostream& operator<<(ostream& os, const A<S>& p);

    template<class S>
    friend bool operator==(const A<S>& p1, const A<S>& p2);   
};

How can I define iterator and const_iterator for my class? (I want to uses the iterators of the vectors instead to implement class iterator and class const_iterator)..


I want (for example) to support in something like that:

A a(5);  
for(A<int>::iterator it = a.begin() ; it != a.end() ; it++) { /* .. */ }
like image 766
Software_t Avatar asked Jul 03 '18 07:07

Software_t


2 Answers

You can simply do this, in C++11:

template<class T>
class A {
    vector<T> arr;
public: 

    using iterator = typename vector<T>::iterator;
    using const_iterator = typename vector<T>::const_iterator;

    const_iterator begin() const { return arr.begin(); }
    iterator       begin()       { return arr.begin(); }
    const_iterator end() const { return arr.end(); }
    iterator       end()       { return arr.end(); }
};

or in C++14:

template<class T>
class A {
    vector<T> arr;
public:
    using iterator = typename vector<T>::iterator;
    using const_iterator = typename vector<T>::const_iterator;

    auto begin() const { return arr.begin(); }
    auto begin()       { return arr.begin(); }
    auto end() const { return arr.end(); }
    auto end()       { return arr.end(); }
};

Then you can both support iterator-based iteration:

A<int> a(5);  
for(A<int>::iterator it = a.begin() ; it != a.end() ; it++) { /* .. */ 
}

And ranged-based for loop:

A a(5);  
for(auto v : a) { /* .. */ 
}

Further explanations on how to support range-based for loop are available here : How to make my custom type to work with "range-based for loops"?

(thanks @JohnML for the edit suggestion to make the answer c++11 compliant!)

like image 191
Olivier Sohn Avatar answered Nov 15 '22 03:11

Olivier Sohn


Simply typedef the vector's existing iterator types into your own class:

template<class T>
class A {
    ...
public:
    typedef vector<T>::iterator iterator;
    typedef vector<T>::const_iterator const_iterator;
    ...
};

Or

template<class T>
class A {
    ...
public:
    using iterator = typename vector<T>::iterator;
    using const_iterator = typename vector<T>::const_iterator;
    ...
};
like image 34
Remy Lebeau Avatar answered Nov 15 '22 04:11

Remy Lebeau