双向迭代器实现

时间:2019-10-31 20:51:13

标签: c++

由于某些原因,我需要实现双向迭代器,一段时间后,我得到了以下结果({add参数告诉迭代器应移向哪一侧(在实现{{1}时避免代码重复) })):

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; } }; } MoveAssignableMoveConstructibleCopyAssignableCopyConstructibleSwappableEqualityComparableLegacyIteratorLegacyInputIteratorLegacyForwardIterator命名的需求。

其中一些要求以操作符重载表示,但是其中的一些我不知道如何实现(也许它们是由其他人自动实现的?),例如:LegacyBidirectionalIterator或{{1 }}(来自here)。第一个问题:我应该如何实施它们?

第二个问题:我的迭代器实现良好吗?它的缺点是什么,我在哪里犯了错误?

P.S。这些问题处于非建设性的边缘,但我确实需要帮助。对不起,我的英语。

1 个答案:

答案 0 :(得分:1)

我发现很难找到一个明确的答案,因此,仅是一些想法可能并不完整,尚需讨论。

  • i->m可以由inline pointer operator->() { return this->currentPosition; }
  • 实施
  • *i++应该已经包含在您的实现中
  • 我看不出有任何理由交换operator=中的所有指针。出于三个原因:

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