按照可怕迭代器的范例,每个值类型的连续迭代器应该只有一个迭代器类型。
下面是迭代器的代码,使用C++11+:
#include <type_traits>
#include <iterator>
template<class T, class U>
struct is_more_cv_qualified : std::integral_constant<bool, std::is_same<T, const volatile U>{}
|| std::is_same<T, const U>{} || std::is_same<T, volatile U>{}>;
struct contiguous_iterator_tag : std::random_access_iterator_tag {};
struct mutable_contiguous_iterator_tag : contiguous_iterator_tag, std::output_iterator_tag {};
template<class T>
struct contiguous_iterator_base {
constexpr bool operator==(contiguous_iterator_base other) const noexcept { return _p == other.p; }
constexpr bool operator!=(contiguous_iterator_base other) const noexcept { return _p != other.p; }
constexpr bool operator<(contiguous_iterator_base other) const noexcept { return _p < other._p; }
constexpr bool operator>(contiguous_iterator_base other) const noexcept { return _p > other._p; }
constexpr bool operator<=(contiguous_iterator_base other) const noexcept { return _p <= other._p; }
constexpr bool operator>=(contiguous_iterator_base other) const noexcept { return _p >= other._p; }
constexpr std::ptrdiff_t operator-(contiguous_iterator_base other) const noexcept { return _p - other._p; }
protected:
constexpr contiguous_iterator_base& operator=(const contiguous_iterator_base&) noexcept = default;
T* _p = nullptr;
};
template<class T>
struct contiguous_iterator : contiguous_iterator_base<std::remove_cv<T>::type>
, std::iterator<typename std::conditional<std::is_const<T>{}, contiguous_iterator_tag, mutable_contiguous_iterator_tag>::type, T> {
constexpr contiguous_iterator() noexcept = default;
template<class U, class = std::enable_if<is_more_cv_qualified<T, U>{}>::type>
constexpr contiguous_iterator(contiguous_iterator<U> other) noexcept : contiguous_iterator_base<std::remove_cv<T>::type>(other) {}
constexpr explicit contiguous_iterator(contiguous_iterator_base<std::remove_cv<T>::type> other) noexcept : decltype(other)(other) {}
constexpr explicit contiguous_iterator(T* p) noexcept { _p = const_cast<decltype(_p)>(p); }
template<class U>
constexpr contiguous_iterator<U> rebind() const noexcept { return contiguous_iterator<U>(_p); }
constexpr T* operator->() const noexcept { return _p; }
constexpr T& operator* () const noexcept { return *_p; }
constexpr T& operator[](std::ptrdiff_t d) const noexcept { return _p[d]; }
constexpr contiguous_iterator& operator++() noexcept { ++_p; return *this; }
constexpr contiguous_iterator operator++(int) noexcept { auto r = *this; ++*this; return r; }
constexpr contiguous_iterator& operator--() noexcept { --_p; return *this; }
constexpr contiguous_iterator operator--(int) noexcept { auto r = *this; --*this; return r; }
constexpr contiguous_iterator& operator+=(std::ptrdiff_t d) noexcept { _p += d; return *this; }
constexpr contiguous_iterator& operator-=(std::ptrdiff_t d) noexcept { _p -= d; return *this; }
constexpr contiguous_iterator operator+(std::ptrdiff_t d) const noexcept { return contiguous_iterator(_p) += d; }
constexpr contiguous_iterator operator-(std::ptrdiff_t d) const noexcept { return contiguous_iterator(_p) -= d; }
protected:
using contiguous_iterator_base<std::remove_cv<T>::type>::_p;
};
// smoke test
int main() {
contiguous_iterator_base<int>{};
contiguous_iterator<int> a;
contiguous_iterator<const int> b;
b = a;
a = b.rebind<int>();
//a.rebind<char>(); error
}发布于 2015-12-14 02:46:27
这里真的没什么可说的。这看起来真不错。
在平等操作符上,您的代码中有几个输入。您比较的是other.p而不是other._p。
我们有这样的构造函数:
constexpr explicit contiguous_iterator(T* p);但这意味着如果我们有contiguous_iterator<Base>,我们可以用一个Derived*来构造它。我们一定要禁止这样做。
同样,rebind<U>也应该被限制在Us身上,他们和T一样,至少也是合格的。
而不是这样写:
constexpr explicit contiguous_iterator(contiguous_iterator_base<std::remove_cv_t<T>> other) noexcept : decltype(other)(other) {}如果添加了一个using base = contiguous_iterator_base<std::remove_cv_t<T>>;,就可以编写:
constexpr explicit(base other) noexcept : base(other) {}这更有道理。
对于类型特征,您始终使用别名模板,但使用的是typename std::conditional<X>::type而不是std::conditional_t。
有些台词真的很长!加一些换行符。
我想最后..。contiguous_iterator<T>实现了简单的T*没有实现的目标吗?
https://codereview.stackexchange.com/questions/113866
复制相似问题