首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于连续迭代器的最后一个词

关于连续迭代器的最后一个词
EN

Code Review用户
提问于 2015-12-14 02:13:16
回答 1查看 556关注 0票数 7

按照可怕迭代器的范例,每个值类型的连续迭代器应该只有一个迭代器类型。

下面是迭代器的代码,使用C++11+:

代码语言:javascript
复制
#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
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2015-12-14 02:46:27

这里真的没什么可说的。这看起来真不错。

Typos

在平等操作符上,您的代码中有几个输入。您比较的是other.p而不是other._p

限制不够

我们有这样的构造函数:

代码语言:javascript
复制
constexpr explicit contiguous_iterator(T* p);

但这意味着如果我们有contiguous_iterator<Base>,我们可以用一个Derived*来构造它。我们一定要禁止这样做。

同样,rebind<U>也应该被限制在Us身上,他们和T一样,至少也是合格的。

添加另一个别名

而不是这样写:

代码语言:javascript
复制
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>>;,就可以编写:

代码语言:javascript
复制
constexpr explicit(base other) noexcept : base(other) {}

这更有道理。

缺失别名

对于类型特征,您始终使用别名模板,但使用的是typename std::conditional<X>::type而不是std::conditional_t

线宽

有些台词真的很长!加一些换行符。

为什么?

我想最后..。contiguous_iterator<T>实现了简单的T*没有实现的目标吗?

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/113866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档