由于某些原因,我需要实现一个双向迭代器,一段时间后,我得到了这个结果(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;
}
};
}
我试图满足 MoveAssignable
、MoveConstructible
、CopyAssignable
、CopyConstructible
、Swappable
、EqualityComparable
、LegacyIterator
、LegacyInputIterator
、LegacyForwardIterator
、LegacyBi DirectionIterator
命名要求.
他们的一些要求是用运算符重载来表达的,但是他们中的一些我不知道如何实现(也许它们被其他的自动实现了?),例如:i->m
或 *i++
(来自 here )。第一个问题:我应该如何实现它们?
第二个问题:我的迭代器实现好吗?它有什么缺点,我哪里出错了?
附注这些问题几乎没有建设性,但我确实需要帮助。对不起我的英语。
最佳答案
我发现很难找到一个明确的答案,所以只是一些想法,这些想法可能不完整,可以讨论。
-
i->m
可以通过inline pointer operator->() { return this->currentPosition; }
来实现 -
*i++
您的实现应该已经涵盖了 我认为没有任何理由交换
operator=
中的所有指针。出于三个原因:- 您正在与局部变量交换值
- 移动构造函数不会交换任何值(
BidirectionalIterator newIt=oldIt;
和BidirectionalIterator newIt(oldIt);
之间的行为会不一致,但实际上并不是因为上一点) - 这些指针不是唯一的资源,因此复制它们并在多个实例之间共享它们没有问题
-
operator=
缺少return
. - 您有
using difference_type = std::ptrdiff_t;
但不实现operator-
这将返回difference_type
,为什么不实现呢? - 反向迭代器可以通过std::reverse_iterator更容易地实现它只会包装你的迭代器并反转++ 和 -- 等等。
- 您可能希望找到一种简单的方法来实现迭代器的 const 版本(始终返回
const T&
或const T*
的版本)。我看到了三个版本:- 复制所有代码
- 使用 const cast
- 使用附加模板参数
bool TIsConst
和using pointer = std::conditional_t<TIsConst, const T*, T*>;
- 使用带参数
const T
的模板化迭代器另一方面可能看起来很容易,但无法满足要求,see this question
关于c++ - 双向迭代器实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58651004/