这个简化的测试用例(按照用户手册中的示例编写)无法编译
#include <range/v3/all.hpp>
#include <vector>
using v = std::vector<int>;
class rows : public ranges::view_facade<rows> {
public:
rows() = default;
explicit rows(const v& data) : it_(data.begin()), end_(data.end()) {}
private:
friend ranges::range_access;
v::const_iterator it_;
v::const_iterator end_;
const int& read() const {
return *it_;
}
bool equal(ranges::default_sentinel) const {
return it_ == end_;
}
void next() {
++it_;
}
};
int main() {
v data{10, 20, 30, 40};
auto rng = rows(data) | ranges::view::unique;
}
编译因static_assert而失败,因为根据view :: unique,我的范围不会对ForwardRange概念建模
但是如果我重写我的类以使用显式游标,则编译成功
class rows : public ranges::view_facade<rows> {
public:
rows() = default;
explicit rows(const v& data) : data_{&data} {}
private:
friend ranges::range_access;
const v* data_;
struct cursor {
cursor() = default;
cursor(v::const_iterator iter) : it{iter} {}
const int& read() const {
return *it;
}
bool equal(const cursor& other) const {
return it == other.it;
}
void next() {
++it;
}
v::const_iterator it;
};
cursor begin_cursor() const {
return {data_->begin()};
}
cursor end_cursor() const {
return {data_->end()};
}
};
为什么第一堂课不是ForwardRange而第二堂课却没问题? view_facade&lt;&gt; ::(begin | end)_cursor()默认返回派生类的实例,所以我不明白为什么它不起作用。
我添加了一个静态断言,以确保range :: range_access :: single_pass_t为false,因此我怀疑该问题与ForwardIterator概念有关。
答案 0 :(得分:3)
您定义equal(ranges::default_sentinel) const
但不定义equal(const rows&)
,因此您的范围的迭代器类型将满足EqualityComparableWith<ranges::default_sentinel>
但不会EqualityComparable
。前向迭代器(和更强大的)需要满足EqualityComparable
,因此rows
满足InputRange
但不满足ForwardRange
。
我建议你定义:
bool equal(const rows& that) const {
return it_ == that.it_;
}