如何使用 private std::vector base class 编写正向迭代器

how to write forward iterator using private std::vector base class

我需要一个向量 class 来公开 std::vector API 的一小部分。一切正常,除了基于范围的。在这里,我尝试实现一个前向迭代器,但它无法编译。

#include <vector>
#include <iostream>

template <class T>
class OwningVector : private std::vector<T*> {
    using super = std::vector<T*>;

public:
    OwningVector() = default;
    ~OwningVector()
    {
        for (T* e : *this)
            delete e;
        super::clear();
    }
    OwningVector(const OwningVector& other)
        : super()
    {
        super::reserve(other.size());
        for (T* e : other)
            super::emplace_back(e->clone());
    }
    OwningVector& operator=(const OwningVector& other)
    {
        if (this == &other)
            return *this;
        OwningVector ret(other);
        swap(*this, ret);
        return *this;
    }

    void emplace_back(T* e) { super::emplace_back(e); }

    size_t size() const { return super::size(); }
    T* const& operator[](int i) const { return super::operator[](i); }
    T* const& at(int i) const { return super::at(i); }
    const T* back() const { return super::back(); }

    // Here the questionable part of my code:

    class Iterator : public std::vector<T*>::iterator {};

    Iterator begin() const { return super::begin(); }
    Iterator end() const { return super::end(); }
    Iterator begin() { return super::begin(); }
    Iterator end() { return super::end(); }
};

class A {
public:
    A(int m) : m(m) {}
    int m;
};

int main() {
    OwningVector<A> v;
    v.emplace_back(new A(1));
    for (const A*const a: v)
        std::cout << a->m << std::endl;
}

编译失败:

h.cpp: In instantiation of ‘OwningVector<T>::Iterator OwningVector<T>::begin() [with T = A]’:
h.cpp:56:27:   required from here
h.cpp:43:43: error: could not convert ‘((OwningVector<A>*)this)->OwningVector<A>::<anonymous>.std::vector<A*, std::allocator<A*> >::begin()’ from ‘std::vector<A*, std::allocator<A*> >::iterator’ to ‘OwningVector<A>::Iterator’
   43 |     Iterator begin() { return super::begin(); }
      |                               ~~~~~~~~~~~~^~
      |                                           |
      |                                           std::vector<A*, std::allocator<A*> >::iterator
h.cpp: In instantiation of ‘OwningVector<T>::Iterator OwningVector<T>::end() [with T = A]’:
h.cpp:56:27:   required from here
h.cpp:44:39: error: could not convert ‘((OwningVector<A>*)this)->OwningVector<A>::<anonymous>.std::vector<A*, std::allocator<A*> >::end()’ from ‘std::vector<A*, std::allocator<A*> >::iterator’ to ‘OwningVector<A>::Iterator’
   44 |     Iterator end() { return super::end(); }
      |                             ~~~~~~~~~~^~
      |                                       |
      |                                       std::vector<A*, std::allocator<A*> >::iterator
class Iterator : public std::vector<T*>::iterator {};

为什么?这看起来像是某种其他语言的实现方式。它也不能保证工作,因为 vector<T*>::iterator 实际上可能是一个指针类型,在这种情况下你不能从它派生。

using Iterator = typename super::iterator;
using ConstIterator = typename super::const_iterator;

ConstIterator begin() const { return super::begin(); }
ConstIterator end() const { return super::end(); }
Iterator begin() { return super::begin(); }
Iterator end() { return super::end(); }

这行得通。 typename 在 C++17 之前是必需的,对于 C++20 可以删除。