The other day I wanted to try writing my own iterators for a vector, of course, the most primitive example, since there is a lot of confusing code in the c++ standards. So the usual iterator for a vector in the forward direction works fine, but there was a problem with the reverse iterator. I have it completely built on the base iterator, only I changed / inverted the operators specifically for the reverse iterator.
template<typename Vector>
class VectorRevIterator : public VectorIterator<Vector> //This is normal (work) vector iterator
{
public:
using Base = VectorIterator<Vector>;
VectorRevIterator(PointerType ptr) noexcept : Base(ptr) {};
VectorRevIterator(const VectorRevIterator& other) : Base(other) { *this = other; };
VectorRevIterator& operator++()
{
Base::operator--(); //--ptr;
return *this;
}
VectorRevIterator operator++(int)
{
VectorRevIterator itr = *this;
Base::operator--(); //--*this;
return itr;
}
VectorRevIterator& operator--()
{
Base::operator++(); //++ptr;
return *this;
}
VectorRevIterator operator--(int)
{
VectorRevIterator itr = *this;
Base::operator++(); //++*this;
return itr;
}
VectorRevIterator& operator+=(const PointerType otherPtr)
{
Base::operator-=(otherPtr); //ptr -= otherPtr;
return *this;
}
VectorRevIterator operator+(const PointerType otherPtr)
{
VectorRevIterator itr = *this;
Base::operator-(otherPtr); // itr -= otherPtr
return *this;
}
VectorRevIterator& operator-=(const PointerType otherPtr) { return Base::operator+=(otherPtr); }
VectorRevIterator operator-(const PointerType otherPtr) { Base::operator+(otherPtr); }
ReferenceType operator*() const { return *ptr; }
PointerType operator->() const { return std::_Const_cast(Base::operator->()); }
};
Access to iterator from Vector:
template<typename T>
class Vector
{
public:
using ValueType = T;
using PointerType = ValueType*;
using ReferenceType = ValueType&;
using ReverseIterator = VectorRevIterator<Vector<T>>;
public:
T* data;
size_t size;
size_t capacity;
...
// construct/destructor
// custom allocator
// index operators
...
ReverseIterator rBegin() { return ReverseIterator(data + size); }
ReverseIterator rEnd() { return ReverseIterator(data); }
};
The problem itself is that when I try to go through all the elements in the opposite direction VectorRevIterator
. When trying to output all this to the console, it seems to shift one element forward and does not see/cannot read the characters of the first element. But then output all the elements, only without the last one.
Here a example:
Vector<String> values;
values.emplaceBack("1");
values.emplaceBack("2");
values.emplaceBack("3");
values.emplaceBack("4");
values.emplaceBack("5");
Vector<String>::ReverseIterator revIt = values.rBegin();
// output with spdlog
for (revIt; revIt != values.rEnd(); ++revIt)
INFO(*revIt); // error on first iteration, but print only 1, 2, 3, 4
// ouput with std::cout
for (revIt; revIt != values.rEnd(); ++revIt)
std::cout << *revIt << std::endl; // doesn't print anything
How solve this problem? To make reverse iterator it just need to revert operators ++
--
+=
-=
and rBegin
rEnd
functions. Or maybe im forgotten about something?