这是我必须为学校解决的练习,所以请给我没有完整的解决方案,只是提示;-)
练习如下:
实现一个封装另一个迭代器(即序列)并执行范围检查的迭代器 使用序列的第一个和最后一个元素初始化迭代器 如果迭代器指向第一个元素并且减少了或者如果迭代器指向最后一个元素并且增加了信号错误 - 选择一个适当的信号形式来表示错误首先我想继承向量容器的迭代器,然后我得到了这个(只是我的“解决方案”的一部分,但我意识到这很糟糕并停止了......):
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; };所以我意识到我并没有真正从vector迭代器继承(我这样做,但我没有使用它)。 使用标准迭代器功能的最简单方法是什么,但是在“顶部”执行范围检查? 如果违反了范围,我可以抛出一个异常,或者设置一个“errorflag”(由boolean“beh”指定),但这不应该是一个问题。
This is a exercise I have to solve for school, so please give me no complete solutions, just hints ;-)
The exercise is the following:
Implement an iterator that encapsulates another iterator (i.e., a sequence) and that performs range checking The iterator is initialized with the first and last element of the sequence If the iterator points to the first element and is decreased OR if the iterator points to the last element and is increased signal an error – choose an appropriate form of signaling the errorFirst I wanted to inherit iterator of vector container, then I got this (just a part of my "solution", but I realized that this is crappy and stopped...):
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; };So I realized that I do not really inherit from vector iterator (I do, but I do not make use of it). What is the easiest way to use functionality of standard iterator, but implement a range check "on top"? If range is violated I can either throw an exception or I set an "errorflag" (specified by boolean "beh") but this should not be a problem to implement.
最满意答案
我认为只存储三个迭代器( 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*(); // ... };Instead of inheriting from the wrapped iterator type, I think it would be much easier to just store three iterators (begin, end and current) and implements the methods that are required for your particular iterator that does bound checking (increment, decrement) and just delegate to the wrapped current iterator the others.
As you've seen, you don't really use the container type, nor its iterator, so you could even pass the iterator type to your template class.
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_; };The methods that you need to implement for your iterator are:
pre- and post-increment pre- and post-decrement dereference operator equality and inequality comparisonYou can get a full list here.
As @Jarod42 mentioned in comments, you don't even need to pass the data type to the template, but you can use std::iterator_traits<Iter> to deduce it:
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*(); // ... };更多推荐
发布评论