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

Multi tool use
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
)..
iterator
const_iterator
class iterator
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++) { /* .. */ }
If you need too many base class methods to be exposed by derived class, it indicates that your derived one is more likely IS-A than HAS-A. But publicly deriving from standard containers is not recommended and is needed in very rare cases. Thus it makes sense to try to revise your class design at first. What additional compared to vector functionality do you want from your class A?
– wtom
Jul 3 at 8:28
2 Answers
2
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!)
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;
...
};
Missing
typename
keywords. (Yes, they're required even though an alias declaration can only be a type.)– aschepler
Jul 3 at 13:44
typename
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Possible duplicate of How to make my custom type to work with "range-based for loops"?
– Olivier Sohn
Jul 3 at 8:07