I wanted to implement an iterator to use a custom class in a for range loop. The iterator access an internal std::vector of std::unique_ptr of a Base class and returns a raw pointer to a child class.
This is what I came up with:
using upBase = std::unique_ptr<Base>;
class Test
{
std::vector<upBase> list;
public:
void Add(upBase&& i) { list.push_back(std::move(i)); }
class iterator
{
upBase* ptr;
public:
iterator(upBase* p) : ptr(p) {}
bool operator!=(const iterator& o) { return ptr != o.ptr; }
iterator& operator++() { ++ptr; return *this; }
Child& operator*() { return *(Child*)(*ptr).get(); }
const Child& operator*() const { return *(Child*)(*ptr).get(); }
};
iterator begin() { return iterator(&list[0]); }
iterator end() { return iterator(&list[list.size()]); }
};
This works fine on the latest compilers (tested on GodBolt with GCC, Clang and MSVC) but when using Visual Studio 2015 the end() method throws a run-time exception:
Debug assertion failed. C++ vector subscript out of range.
I search the internet for a proper way to access the address of the one-past-end element of a std::vector, but didn't find anything except complicated pointer arithmetic.
I finally came up with the following implementation for the begin() and end() methods:
iterator begin() { return iterator(&list.front()); }
iterator end() { return iterator(&list.back() + 1); }
This doesn't complain at run-time. Is it the correct way to access the address of the one-past-end element of an std::array or std::vector?
If not, what would be the proper way?