For flexibility you may just write an adapter:
#include <type_traits>
template <typename Iterator>
class random_access_pointer_iterator
{
// Types
// =====
public:
typedef Iterator iterator_type;
typedef std::random_access_iterator_tag iterator_category;
using difference_type = typename iterator_type::difference_type;
using pointer = decltype(&**std::declval<iterator_type>());
using value_type = typename std::remove_pointer<pointer>::type;
typedef value_type& reference;
// Construction
// ============
public:
explicit random_access_pointer_iterator(iterator_type iterator)
: m_iterator(iterator)
{}
// Element Access
// ==============
public:
const iterator_type& base() const { return m_iterator; }
iterator_type& base() { return m_iterator; }
operator iterator_type () const { return m_iterator; }
// Iterator
// ========
public:
reference operator * () const { return **m_iterator; }
pointer operator -> () const { return &(**m_iterator); }
random_access_pointer_iterator& operator ++ () {
++m_iterator;
return *this;
}
random_access_pointer_iterator operator ++ (int) {
random_access_pointer_iterator tmp(*this);
++m_iterator;
return tmp;
}
random_access_pointer_iterator& operator += (difference_type n) {
m_iterator += n;
return *this;
}
random_access_pointer_iterator& operator -- () {
--m_iterator;
return *this;
}
random_access_pointer_iterator operator -- (int) {
random_access_pointer_iterator tmp(*this);
--m_iterator;
return tmp;
}
random_access_pointer_iterator& operator -= (difference_type n) {
m_iterator -= n;
return *this;
}
private:
iterator_type m_iterator;
};
template <typename Iterator>
inline random_access_pointer_iterator<Iterator> operator + (
random_access_pointer_iterator<Iterator> i,
typename random_access_pointer_iterator<Iterator>::difference_type n) {
return i += n;
}
template <typename Iterator>
inline random_access_pointer_iterator<Iterator> operator - (
random_access_pointer_iterator<Iterator> i,
typename random_access_pointer_iterator<Iterator>::difference_type n) {
return i -= n;
}
template <typename Iterator>
inline typename random_access_pointer_iterator<Iterator>::difference_type
operator - (
const random_access_pointer_iterator<Iterator>& a,
const random_access_pointer_iterator<Iterator>& b) {
return a.base() - b.base();
}
template <typename Iterator>
inline bool operator == (
const random_access_pointer_iterator<Iterator>& a,
const random_access_pointer_iterator<Iterator>& b) {
return a.base() == b.base();
}
template <typename Iterator>
inline bool operator != (
const random_access_pointer_iterator<Iterator>& a,
const random_access_pointer_iterator<Iterator>& b) {
return a.base() != b.base();
}
template <typename Iterator>
inline bool operator < (
const random_access_pointer_iterator<Iterator>& a,
const random_access_pointer_iterator<Iterator>& b) {
return a.base() < b.base();
}
template <typename Iterator>
inline bool operator <= (
const random_access_pointer_iterator<Iterator>& a,
const random_access_pointer_iterator<Iterator>& b) {
return a.base() <= b.base();
}
template <typename Iterator>
inline bool operator > (
const random_access_pointer_iterator<Iterator>& a,
const random_access_pointer_iterator<Iterator>& b) {
return a.base() > b.base();
}
template <typename Iterator>
inline bool operator >= (
const random_access_pointer_iterator<Iterator>& a,
const random_access_pointer_iterator<Iterator>& b) {
return a.base() >= b.base();
}
#include <cassert>
#include <memory>
#include <vector>
int main() {
using vector = std::vector<std::shared_ptr<int>>;
auto p = std::make_shared<int>(0);
vector v = { p };
using iterator = random_access_pointer_iterator<vector::iterator>;
iterator a(v.begin());
iterator b(v.end());
assert(*a == 0);
assert(a.operator -> () == &*p);
++a;
assert(a == b);
--a;
assert(a != b);
assert(a++ != b);
assert(a-- == b);
assert(a + 1 == b);
assert(a == b - 1);
assert(b - a == 1);
assert(a < b);
assert(a <= b);
assert(b > a);
assert(b >= a);
}
Having this, you can use any random access iterator (vector, deque, ... ) and use any pointer type (raw pointer, shared_ptr, ...)
Note: In your case - when you derive from the iterator of the vector you will have to adjust the type definitions, too.
Note: I do not like 'random_access_pointer_iterator', but I have nothing better on my mind.
usingdeclarations to re-export members you want to be accessible.