I have a class with an standard container member, and I’m wondering is that possible that I make an own iterator with a specific route, for example it goes back and forth, and after that stops.
template<class T>
class compressed_string {
vector<T> v;
public:
typedef typename std::vector<T>::iterator iterator;
iterator begin() { return v.begin(); }
iterator end() { return v.end(); }
compressed_string& add(const T& elem) {
v.push_back(elem);
return *this;
}
basic_string<T> not_nice_way_to_make_real_string() {
basic_string<T> tmp;
for(iterator i = v.begin(); i < v.end(); ++i)
tmp += *i;
for(iterator i = --v.end(); i >= v.begin(); --i)
tmp += *i;
return tmp;
}
};
main:
compressed_string<char> s;
s.add('q').add('w').add('e').add('w');
cout << s.not_nice_way_to_make_real_string(); // q w e w w e w q
cout << endl
for ( compressed_string<char>::iterator i = s.begin(); i < s.end(); ++i )
cout << *i;
So with this iterator member the output would be the same in this two lines.
How is this possible?
You’ll need an iterator that stores a bit of state:
v_itoverv)bool forward)v_begin = v.begin()andv_end = v.end())and some otherwise invalid iterator to represent the end, such as
{v_end, backward}).Then implement the increment operator along the lines of:
and similarly for decrement, if you want a bidirectional iterator; in which case, it would be polite to provide a
reverse_iteratortoo. You should provide both pre- and post-increment forms.You’ll also need
==and!=comparisons, comparing bothv_itandforward, and dereference operators*and->that dereferencev_it, and suitablebeginandendfunctions; for bonus points, aconst_iteratorwould be nice.Note that you’ll need random access if you really want the code in your question (
i < s.end()rather than the more generici != s.end()) to work; that’s entirely possible, but rather excessive if you don’t otherwise need it.UPDATE: as noted in the comments, this particular implementation could probably be improved a bit; for example, it’s possible to remove the need to store
v_beginif you’re a bit careful about how you define the end iterator.