c++ - 如何编写可与 STL 算法一起使用的随机访问自定义迭代器?

标签 c++ iterator

#include <iostream>
#include <vector>
#include <algorithm>

template <typename T>
class _iterator
{
    T* ptr;

public:

    using iterator_category = std::random_access_iterator_tag;
    using value_type        = T;
    using reference         = T&;
    using pointer           = T*;
    using difference_type   = unsigned long long;

    _iterator(T* ptr) : ptr(ptr) {}

    reference operator* () { return *ptr; }
    pointer   operator->() { return  ptr; }

    _iterator& operator++() { ptr++; return *this; }
    _iterator& operator--() { ptr--; return *this; }

    difference_type operator-(const _iterator& it) { return this->ptr - it.ptr; }

    _iterator operator+(const difference_type& diff) { return _iterator(ptr + diff); }
    _iterator operator-(const difference_type& diff) { return _iterator(ptr - diff); }

    bool operator==(const _iterator& it) { return this->ptr == it.ptr; }
    bool operator!=(const _iterator& it) { return this->ptr != it.ptr; }
    bool operator< (const _iterator& it) { return this->ptr <  it.ptr; }

    operator _iterator<const T>() const { return _iterator<const T>(ptr); }
};

template <typename T>
class X
{
    std::vector<T> data;

public:

    using iterator = _iterator<T>;
    using const_iterator = _iterator<const T>;

    void push_back(T t)
    {
        data.push_back(t);
    }

    iterator begin()
    {
        return iterator(&data[0]);
    }

    iterator end()
    {
        return iterator(&data[0] + data.size());
    }
};

int main()
{
    X<int> x;

    for (int i = 9; i >= 0; i--)
        x.push_back(i);

    // 1 ------------------------------------------------------------------------

    // C2780    'void std::_Sort_unchecked(_RanIt,_RanIt,iterator_traits<_Iter>::difference_type,_Pr)': expects 4 arguments - 3 provided
    // C2672    '_Sort_unchecked': no matching overloaded function found
    // C2678    binary '-': no operator found which takes a left - hand operand of type 'const _RanIt' (or there is no acceptable conversion)

    std::sort(x.begin(), x.end());


    // 2 ------------------------------------------------------------------------

    // C2666    '_iterator<T>::operator -': 2 overloads have similar conversions
    // C2512    '_iterator<T>': no appropriate default constructor available

    for (X<int>::iterator it = x.end() - 1; it >= x.begin(); --it)
        std::cout << *it << ' ';
    std::cout << std::endl;
}

我正在尝试为自定义容器编写随机访问迭代器。我面临几个问题:
  • 不能在自定义容器上使用 STL 算法。
  • 如果我从迭代器中减去一个数字,我会收到一个错误,告诉我我有 2 个重载。

  • 错误写在与它对应的每一段代码之上。另外我不确定我定义的方式 iteratorconst_iterator是否有效。我在这里做错了什么以及如何解决它们?

    最佳答案

    // C2678    binary '-': no operator found which takes a left - hand operand of type 'const _RanIt' (or there is no acceptable conversion)
    

    如果您将以下函数标记为 const :
    difference_type operator-(const _iterator& it) const { return this->ptr - it.ptr; }
    

    您将开始解决一些问题。我没有检查这是否涵盖了所有情况。但总的来说,尽你所能const有很大帮助。

    关于c++ - 如何编写可与 STL 算法一起使用的随机访问自定义迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61208870/

    相关文章:

    c++ - 当我在 C++ 中将 float 变量分配给 int 变量时会发生什么?

    c++ - 是否有像 std::accumulate 这样的东西在迭代器上运行?

    php - SplPriorityQueue::next() 正在删除项目

    c++ - 使用反向迭代器 boost ptree 失败

    c++ - 当单击按钮隐藏位于其他类中的另一个按钮时

    c++ - 是否有用于 SDL 的 C++ 包装器/绑定(bind)?

    c++ - 为 sf::String 使用字符串文字时出现链接器错误

    c++ - std::remove_if 不删除所有项目

    sorting - 如何检查切片是否已排序?

    c# - 如何在 C# 中创建类型化的 IEnumerable?