双向迭代器实现

Bidirectional iterator implementation

本文关键字:实现 迭代器      更新时间:2023-10-16

由于某些原因,我需要实现双向迭代器,一段时间后,我得到了以下结果(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;
}
};
}

我试图满足MoveAssignableMoveConstructibleCopyAssignableCopyConstructibleSwappableEqualityComparableLegacyIteratorLegacyInputIteratorLegacyForwardIteratorLegacyBidirectionalIterator命名的要求。

他们的一些需求用运算符重载来表达,但其中一些我不知道如何实现(也许,它们是由其他运算符自动实现的?(,例如:i->m*i++(从这里开始(。第一个问题:我应该如何实施它们?

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

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

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

  • 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-,它会返回difference_type,为什么不实现它呢
  • 通过std::Reverse_iterator可以更容易地实现反向迭代器,它只会包装迭代器并反转++和--等等
  • 您可能想找到一种简单的方法来实现迭代器的const版本(一个总是返回const T&const T*的版本(。我看到了三个版本:
    • 复制所有代码
    • 使用const强制转换
    • 使用附加模板参数bool TIsConstusing pointer = std::conditional_t<TIsConst, const T*, T*>;
    • 另一方面,使用带有参数const T的模板迭代器可能看起来很容易,但不能满足要求,请参阅此问题