我在说是一个RandomAccessIterator - 这有关系吗?

时间:2016-06-21 17:52:21

标签: c++ iterator language-lawyer

我编写了一个类似于迭代器的RandIt类(下面的代码),但只要取消引用就会返回随机整数。主要用例是使用随机数据初始化向量,如

std::vector<int> v(RandIt<0,99>{}, RandIt<0,99>{50});

生成0到99之间的50个数字。

typedef RandIt::iterator_categorystd::random_access_iterator_tag,因为

  • 它必须至少是一个ForwardIterator,用于向量构造函数,以std::distance分配合适的空间来构建。否则使用emplace_back,重新分配和复制。
  • 需要将std::distance的RandomAccessIterator作为常量时间,而不是在循环中递增和测试。

然而,这是一个谎言,因为取消引用RandIt会返回int的值,并且ForwardIterators和better都需要返回对内存中对象的引用。

(由于Forw​​ardIterator的“多通道保证”失败也可能是谎言:再次检查序列会产生不同的结果。但cppreference给出“正式”版本

  

表达式(void)++It(a), *a等同于表达式*a

对于某些“等效”值,似乎是真的。)

因此,我绝对违反了规则,声称自己不是。尽管如此,它似乎有效。

这会咬我吗?说谎的潜在影响是什么?

#include <random>
#include <iterator>

template <int min, int max>
struct RandIt {
    typedef int difference_type;
    typedef int value_type;
    typedef const int* pointer;
    typedef const int& reference;
    typedef std::random_access_iterator_tag iterator_category; // this is a lie

    static std::knuth_b rng;
    static std::uniform_int_distribution<int> idist;
    int i;

    explicit RandIt(int i = 0) : i{i} {}

    int operator*() const {return idist(rng);}
    int operator[](int) const {return idist(rng);}

    RandIt& operator++() {++i; return *this;}
    RandIt  operator++(int) {return RandIt{i++};}
    RandIt& operator--() {--i; return *this;}
    RandIt  operator--(int) {return RandIt{i--};}
    RandIt& operator+=(int k) {i += k; return *this;}
    RandIt& operator-=(int k) {i -= k; return *this;}
    RandIt  operator+ (int k) const {return RandIt{i+k};}
    RandIt  operator- (int k) const {return RandIt{i-k};}
    friend RandIt operator+(int k, RandIt a) {return RandIt{k + a.i};}

    friend int  operator- (RandIt a, RandIt b) {return a.i - b.i;}
    friend bool operator==(RandIt a, RandIt b) {return a.i == b.i;}
    friend bool operator!=(RandIt a, RandIt b) {return a.i != b.i;}
    friend bool operator<=(RandIt a, RandIt b) {return a.i <= b.i;}
    friend bool operator< (RandIt a, RandIt b) {return a.i < b.i;}
    friend bool operator>=(RandIt a, RandIt b) {return a.i >= b.i;}
    friend bool operator> (RandIt a, RandIt b) {return a.i > b.i;}
};


template <int min, int max>
std::knuth_b RandIt<min, max>::rng{std::random_device{}()};
// On some platforms (mingw), random_device is deterministic, so rng 
// will always produce the same values.

template <int min, int max>
std::uniform_int_distribution<int> RandIt<min, max>::idist{min, max};

See it on Coliru

0 个答案:

没有答案