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

Nic*_*teo 6 c++ iterator language-lawyer

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

std::vector<int> v(RandIt<0,99>{}, RandIt<0,99>{50});
Run Code Online (Sandbox Code Playgroud)

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

typedef RandIt::iterator_categorystd::random_access_iterator_tag因为

  • 它至少需要一个ForwardIterator,用于向量构造函数分配适当数量的空间来构建,用std::distance.否则emplace_back使用,重新分配和复制.
  • 它需要是RandomAccessIterator std::distance才能保持恒定时间,而不是在循环中递增和测试.

但是,这是一个谎言,因为取消引用RandIt会返回一个intby值,并且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};
Run Code Online (Sandbox Code Playgroud)

在Coliru看到它.