我有一个包含 std::shared_ptr
私有(private)集合的类,例如:
class Foo
{
private:
using Bars = std::vector<std::shared_ptr<Bar>>;
Bars items_;
}
给定一个 Foo
的实例,我希望能够直接迭代 items_
中的 Bar
对象——实际上隐藏了集合包含指针。我相信 Bars::const_iterator
唯一需要更改的是 operator*
,是否可以从它派生并实现 operator*
>?即
class Iterator : public Bars::const_iterator
{
public:
Iterator(Bars::const_iterator it) : Bars::const_iterator {it} {}
const string& operator*() const
{
return *Bars::const_iterator::operator*();
}
};
然后为Foo
提供begin
和end
方法:
Foo::Iterator Foo::begin() const noexcept { return Iterator {std::cbegin(items_)}; }
Foo::Iterator Foo::end() const noexcept { return Iterator {std::cend(items_)}; }
最佳答案
为了灵 active ,您可以只编写一个适配器:
#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);
}
有了这个,您就可以使用任何随机访问迭代器(vector、deque、...)并使用任何指针类型(原始指针、shared_ptr、...)
注意:在您的情况下 - 当您从 vector 的迭代器派生时,您也必须调整类型定义。
注意:我不喜欢“random_access_pointer_iterator”,但我没有更好的想法。
关于c++ - 从标准容器迭代器派生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35206816/