实现自定义迭代器以使用std :: sort

kei*_*ith 2 c++11

我的目标是学习如何从头开始编写自定义迭代器.我写了以下迭代器:

#include <iterator>

template<class D>
class SpanIterator final : public std::iterator<std::random_access_iterator_tag, D>
{
private:
    D* _data;

public:
    explicit SpanIterator(D* data) :
        _data{ data }
    {
    }

    SpanIterator(const SpanIterator& itertator) = default;

    SpanIterator& operator=(const SpanIterator& iterator) = default;

    SpanIterator& operator=(D* data)
    {
        _data = data;

        return *this;
    }

    operator bool() const
    {
        return _data != nullptr;
    }

    bool operator==(const SpanIterator& itertator) const
    {
        return _data == itertator._data;
    }

    bool operator!=(const SpanIterator& itertator) const
    {
        return _data != itertator._data;
    }

    SpanIterator& operator+=(const std::ptrdiff_t& movement)
    {
        _data += movement;

        return *this;
    }

    SpanIterator& operator-=(const std::ptrdiff_t& movement)
    {
        _data -= movement;

        return *this;
    }

    SpanIterator& operator++()
    {
        ++_data;

        return *this;
    }

    SpanIterator& operator--()
    {
        --_data;

        return *this;
    }

    SpanIterator operator++(int)
    {
        auto temp = *this;

        ++_data;

        return temp;
    }

    SpanIterator operator--(int)
    {
        auto temp = *this;

        --_data;

        return temp;
    }

    SpanIterator operator+(const std::ptrdiff_t& movement)
    {
        auto oldPtr = _data;

        _data += movement;

        auto temp = *this;

        _data = oldPtr;

        return temp;
    }

    SpanIterator operator-(const std::ptrdiff_t& movement)
    {
        auto oldPtr = _data;

        _data -= movement;

        auto temp = *this;

        _data = oldPtr;

        return temp;
    }

    D& operator*()
    {
        return *_data;
    }

    const D& operator*() const
    {
        return *_data;
    }

    D& operator->()
    {
        return _data;
    }
};
Run Code Online (Sandbox Code Playgroud)

我正在测试这样:

#include <iostream>
#include <array>

int main()
{
    std::array<double, 3> values = { 1, 2, 1 };

    SpanIterator<double> begin{ values.data() };
    SpanIterator<double> end{ values.data() + values.size() };

    std::sort(begin, end);

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

但是它无法编译,给出以下错误:

  • 错误C2666'SpanIterator :: operator - ':2重载
  • 错误C2780'void std :: _ Sort_unchecked1(_RanIt,_RanIt,_Diff,_Pr&)':需要4个参数 - 提供3个参数

如果我删除SpanIterator operator-(const std::ptrdiff_t& movement)我得到不同的错误:

  • 'void std :: _ Guess_median_unchecked(_RanIt,_RanIt,_RanIt,_Pr&)':无法从'int'中推断'_RanIt'的模板参数
  • '_Guess_median_unchecked':找不到匹配的重载函数
  • 错误C2100非法间接

eca*_*mur 5

您缺少运算符来支持以下操作(迭代器类型的值ab位置SpanIterator<...>):

  • b - a
  • a < b(和剩下的比较,虽然大多数实现std::sort不使用它们).

例如,您可以提供以下成员运算符重载:

std::ptrdiff_t operator-(SpanIterator const&) const;
bool operator<(SpanIterator const&) const;
// etc.
Run Code Online (Sandbox Code Playgroud)

(请注意,非成员重载通常是首选:运算符重载)

此外,你operator bool应该explicit避免的暧昧过载a + n,n + a并且b - a操作(其中n为您的区别类型,即值std::ptrdiff_t).