c++ - 双向迭代器实现

标签 c++

由于某些原因,我需要实现一个双向迭代器,一段时间后,我得到了这个结果(add参数告诉迭代器应该移动到哪一边(为了避免代码重复,在实现reverse_iterator)):

#include <iterator>

namespace gph {
    template <typename T, int add> class BidirectionalIterator;

    template<typename T, int add>
    void swap(BidirectionalIterator<T, add>& it1, BidirectionalIterator<T, add>& it2) {
        it1.swap(it2);
    }

    template<typename T, int add>
    class BidirectionalIterator {
    private:
        T *currentPosition, *begin, *end;
    public:
        using difference_type = std::ptrdiff_t;
        using value_type = T;
        using pointer = T*;
        using reference = T&;
        using iterator_category = std::bidirectional_iterator_tag;

        inline BidirectionalIterator(T* currentPosition, T* begin, T* end):currentPosition(currentPosition), begin(begin), end(end) {}

        //copy constructor
        inline BidirectionalIterator(const BidirectionalIterator& iterator)
            :BidirectionalIterator(iterator.currentPosition, iterator.begin, iterator.end) {}

        //move constructor
        inline BidirectionalIterator(BidirectionalIterator&& iterator) noexcept
            :BidirectionalIterator(iterator.currentPosition, iterator.begin, iterator.end) {}

        //copy and move assignment statement
        inline BidirectionalIterator& operator=(BidirectionalIterator iterator) {
           gph::swap(*this, iterator);
        }

        inline void swap(BidirectionalIterator& iterator) {
            std::swap(currentPosition, iterator.currentPosition);
            std::swap(begin, iterator.begin);
            std::swap(end, iterator.end);
        }

        inline reference operator*() const {
            return *currentPosition; //dangerous if the iterator is in not-dereferenceable state
        }

        inline BidirectionalIterator& operator++() {
            if (currentPosition != end) currentPosition += add;

            return *this;
        }

        inline bool operator==(const BidirectionalIterator& iterator) const {
            return currentPosition == iterator.currentPosition;
        }

        inline bool operator!=(const BidirectionalIterator& iterator) const {
            return !(*this == iterator);
        }

        inline BidirectionalIterator operator++(int) {
            BidirectionalIterator past = *this;

            ++*this;

            return past;
        }

        inline BidirectionalIterator& operator--() {
            if (currentPosition != begin) currentPosition -= add;

            return *this;
        }

        inline BidirectionalIterator operator--(int) {
            BidirectionalIterator past = *this;

            --*this;

            return past;
        }
    };
}

我试图满足 MoveAssignableMoveConstructibleCopyAssignableCopyConstructibleSwappableEqualityComparableLegacyIteratorLegacyInputIteratorLegacyForwardIteratorLegacyBi DirectionIterator 命名要求.

他们的一些要求是用运算符重载来表达的,但是他们中的一些我不知道如何实现(也许它们被其他的自动实现了?),例如:i->m*i++ (来自 here )。第一个问题:我应该如何实现它们?

第二个问题:我的迭代器实现好吗?它有什么缺点,我哪里出错了?

附注这些问题几乎没有建设性,但我确实需要帮助。对不起我的英语。

最佳答案

我发现很难找到一个明确的答案,所以只是一些想法,这些想法可能不完整,可以讨论。

  • i->m可以通过inline pointer operator->() { return this->currentPosition; }来实现
  • *i++您的实现应该已经涵盖了
  • 我认为没有任何理由交换 operator= 中的所有指针。出于三个原因:

    1. 您正在与局部变量交换值
    2. 移动构造函数不会交换任何值( BidirectionalIterator newIt=oldIt;BidirectionalIterator newIt(oldIt); 之间的行为会不一致,但实际上并不是因为上一点)
    3. 这些指针不是唯一的资源,因此复制它们并在多个实例之间共享它们没有问题
  • operator=缺少 return .
  • 您有using difference_type = std::ptrdiff_t;但不实现 operator-这将返回 difference_type ,为什么不实现呢?
  • 反向迭代器可以通过std::reverse_iterator更容易地实现它只会包装你的迭代器并反转++ 和 -- 等等。
  • 您可能希望找到一种简单的方法来实现迭代器的 const 版本(始终返回 const T&const T* 的版本)。我看到了三个版本:
    • 复制所有代码
    • 使用 const cast
    • 使用附加模板参数 bool TIsConstusing pointer = std::conditional_t<TIsConst, const T*, T*>;
    • 使用带参数 const T 的模板化迭代器另一方面可能看起来很容易,但无法满足要求,see this question

关于c++ - 双向迭代器实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58651004/

相关文章:

c++ - gcc -funit-at-a-time 导致编译失败

c++ - cv::Mat 灰度样式转换

python - 如何在 Win 7 64 位上安装 python-Levenshtein 或其他 C/C++ 包

C++ char* 到 int 错误

c++ - Visual Studio 2013 在/OPT :ICF? 存在的情况下是否正确优化

c++ - 使自动隐藏任务栏在窗口最大化时可见而不取消隐藏

c++ - 是否有 STL 或 boost 函数来确定字符串是否为数字?

c++ - 虚方法只适用于基类指针

c++ - 就处理器时间而言,fmod 有多昂贵?

c++ - 在 Linux 上使用 libserial 将 ASCII 控制字符发送到串行设备