带范围检查的自制迭代器
Self made iterator with range checking
这是我必须为学校解决的一个练习,所以请不要给我完整的解决方案,只是提示;-)
练习如下:
- 实现一个迭代器,该迭代器封装另一个迭代器(即序列)并执行范围检查
- 迭代器是用序列的第一个和最后一个元素初始化的
- 如果迭代器指向第一个元素并减小,或者如果迭代者指向最后一个元素并增大,则表示错误——选择适当的错误信号形式
首先我想继承向量容器的迭代器,然后我得到了这个(只是我"解决方案"的一部分,但我意识到这很糟糕,并停止了…):
template <typename T>
class myIter : std::vector<T>::iterator
{
public:
myIter( typename std::vector<T>::iterator start,
typename std::vector<T>::iterator end,
typename std::vector<T>::iterator pos,
bool behaviour=false) : s(start), e(end), p(pos), beh(behaviour)
{overflowFlag = false;};
typename std::vector<T>::iterator & operator++();
typename std::vector<T>::iterator & operator--();
typename std::vector<T>::iterator operator++(int);
typename std::vector<T>::iterator operator--(int);
typename std::vector<T>::iterator & operator+=(int);
typename std::vector<T>::iterator & operator-=(int);
typename std::vector<T>::iterator operator+(int);
typename std::vector<T>::iterator operator-(int);
myIter & operator=(const myIter&) = delete;
T operator*(){ return *p;};
bool getFlag() {return overflowFlag;};
private:
typename std::vector<T>::iterator s, e, p;
bool beh;
bool overflowFlag; // is set if beh = false. otherwise exception;
};
所以我意识到我并没有真正继承向量迭代器(我继承了,但我没有使用它)。使用标准迭代器功能,但实现"顶部"范围检查的最简单方法是什么?如果违反了范围,我可以抛出异常或设置"errorflag"(由布尔值"beh"指定),但实现起来应该不会有问题。
我认为只存储三个迭代器(begin
、end
和current
)并实现特定迭代器所需的方法会容易得多,这些迭代器进行绑定检查(递增、递减),并将其他迭代器委托给包装的current
迭代器。
正如您所看到的,您并没有真正使用容器类型,也没有使用它的迭代器,所以您甚至可以将迭代器类型传递给您的模板类。
template < typename T, typename Iter >
class bound_checked_iterator {
public:
bound_checked_iterator(Iter begin, Iter end)
: begin_(begin), end_(end), current_(begin) {}
// implements the different methods
bound_checked_iterator operator++();
bound_checked_iterator operator--();
bound_checked_iterator operator++(int);
bound_checked_iterator operator--(int);
T& operator *();
const T& operator *() const;
bool operator ==(bound_checked_operator const& other) const;
bool operator !=(bound_checked_operator const& other) const;
private:
Iter begin_, end_, current_;
};
迭代器需要实现的方法有:
- 增量前后
- 减量前后
- 解引用运算符
- 平等与不平等比较
您可以在此处获得完整列表。
正如@Jarod42在评论中提到的,您甚至不需要将数据类型传递给模板,但您可以使用std::iterator_traits<Iter>
来推导它:
template < typename Iter >
class bound_checked_iterator {
public:
bound_checked_iterator(Iter begin, Iter end)
: begin_(begin), end_(end), current_(begin) {}
// ...
typename std::iterator_traits<Iter>::reference operator*();
// ...
};
目标是在任意迭代器类型之上添加行为。您正在编写的类将是泛型的,但它的大部分实际"迭代器性"将推迟到它的模板参数:让我们将I
称为"迭代者"。
无论您在哪里使用过std::vector<T>::iterator
,请改用普通I
。(当你对代码进行推理时,用一个具体的类型替换I
可能会有所帮助。例如,当对char[]
数组进行迭代时,I
将是char*
。)
你的课的基本框架看起来像:
template <typename I>
class myIter
{
public:
myIter(I start, I end, I pos);
private:
I s, e, p;
};
在各种突变体(operator++
、--
等)中,您将对照s
和e
检查p
,以确保其保持在这些范围内。
- 转到基于范围的 for 循环中的下一个迭代器
- C++:返回一个基于范围 for 循环迭代器,其中包含继承对象
- 迭代器范围的平衡分区,没有LegacyRandomAccessIterator
- 为什么范围算法与 std 的迭代器不兼容?
- Deque 迭代器超出范围
- unordered_set范围插入与迭代器
- 类型不可知的抽象以使用相同的运行时接口处理正向和反向迭代器和范围?
- C 迭代器范围使用指针到数组
- 将迭代器范围复制到矢量而不重复
- 在 std::vector 中插入迭代器范围
- 有效的迭代器范围从堆栈上的char
- 获取迭代器范围的每个第 n 个元素
- 是否可以将基于范围的for循环与迭代器范围一起使用
- <algorithm>在同一输入迭代器范围内并排运行两个
- std::不带模板的数组迭代器范围
- 迭代器范围矢量构造或矢量擦除更快
- 返回迭代器范围(主列表的子集)
- 为什么标准不允许 std::for_each 对无效的随机访问迭代器范围有明确定义的行为?
- 使用不同类型容器的迭代器范围初始化容器
- 多态过滤器迭代器范围