如何为我的容器实现随机访问迭代器?
How can I implement random access iterators for my container?
这是容器的头文件,包括尝试实现随机访问迭代器:
using namespace std;
template <class Element, class Compare = std::equal_to<Element>>
class UniqueArray {
public:
Element** data;
unsigned int curr_size;
unsigned int max_size;
int* availability_array;
explicit UniqueArray(unsigned int size);
UniqueArray(const UniqueArray& other);
~UniqueArray();
// UniqueArray& operator=(const UniqueArray&) = delete;
unsigned int insert(const Element& element);
bool getIndex(const Element& element, unsigned int& index) const;
const Element* operator[] (const Element& element) const;
bool remove(const Element& element);
unsigned int getCount() const;
unsigned int getSize() const;
class Filter {
public:
virtual bool operator() (const Element&) const = 0;
};
UniqueArray filter(const Filter& f) const;
class UniqueArrayIsFullException{};
typedef Element ua_iterator;
typedef const Element ua_const_iterator;
ua_iterator begin(){
return **data;
}
ua_const_iterator begin() const {
return **data;
}
ua_iterator end(){
return *(*data + max_size);
}
ua_const_iterator end() const {
return *(*data + max_size);
}
};
我得到的错误摘要:
error: no match for ‘operator++’
error: no match for ‘operator*’
error: no type named ‘value_type’ in ‘struct std::iterator_traits<MtmParkingLot::Vehicle>
error: no match for ‘operator!=’
error: no match for ‘operator-’
在我的实现中,Element
得到了Vehicle
,所有这些缺少的运算符都引用了Vehicle
我不太确定如何处理这些错误,因为例如减去Vehicles
是没有意义的。
如果希望迭代器在取消引用对象时返回对对象的引用,则必须定义一个特殊的Iterator
类来执行此操作。有了boost::indirect_iterator
这很简单:
#include <boost/iterator/indirect_iterator.hpp>
template <class Element, class Compare = std::equal_to<Element>>
class UniqueArray {
// ...
auto begin() {
return boost::indirect_iterator<Element**, Element>(data_);
}
auto end() {
return boost::indirect_iterator<Element**, Element>(data_ + curr_size);
}
};
简单演示
如果你想自己编码,这个想法是:
template<class Element>
class UniqueArray {
public:
//...
class Iterator {
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = Element;
using reference = Element&;
// ...
Iterator(Element** d) : data(d) { }
reference operator*() {
return **data;
}
Iterator& operator++() {
++data;
return *this;
}
friend bool operator!=(Iterator it1, Iterator it2) {
return it1.data != it2.data;
}
// ...
private:
Element** data;
};
Iterator begin() {
return Iterator(data);
}
Iterator end() {
return Iterator(data + curr_size);
}
};
请注意,完全随机访问迭代器需要实现许多其他成员和非成员函数。您可能希望使其成为前向迭代器以简化一些事情。
简单演示
如果你在没有类型别名的情况下编写它,你会得到这样的定义
Element begin(){
return **data;
}
并像
UniqueArray<Vehicle>::ua_iterator it = something.begin();
it++;
成为
Vehicle it = something.begin();
it++;
这使得错误的原因更加明显 - 您正在尝试将迭代器操作应用于元素类型。
如果您对迭代生成Element*
感到满意,则简单的解决方案是
typedef Element** ua_iterator;
ua_iterator begin(){
return data;
}
ua_iterator end(){
return data + curr_size;
}
以及康斯特版本的类似情况。
然后你可以写
UniqueArray<Vehicle>::ua_iterator it = something.begin();
Vehicle* v = *it;
如果你想让迭代产生Element&
,你需要编写一个具有适当重载和特征的迭代器类。
这不是很困难,但它变得乏味。
相关文章:
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?
- 如何为我的容器实现随机访问迭代器?
- 对于C++随机访问迭代器(矢量迭代器),迭代器之间的差异是如何计算的?
- 对于随机访问迭代器(矢量迭代器),迭代器C++样式指针吗?
- Deque 中元素的随机访问如何提供恒定的时间复杂度?
- C++ STL 数据结构常时按索引推送/弹出/随机访问,并具有指向元素的可靠指针
- SFINAE - 检测类型 T 是指针、数组还是带有随机访问运算符的容器,以及给定的值类型
- 随机访问迭代器:我错过了什么?
- 随机访问元组向量中的元组值
- 有没有办法在C++中制作无锁"counter"随机访问迭代器?
- 当 95% 情况下的值为 0 或 1 时,对非常大的数组进行随机访问的任何优化
- 如何确保函数模板的参数是随机访问迭代器
- C++基于现有随机访问迭代器的反向迭代器
- C++ 写入随机访问文件
- 如何实现随机访问迭代器的"less than operator"?
- 随机访问迭代器和Deque
- 如何创建一个随机访问式的Rreference以访问.RC文件中定义的资源
- 在链表上实现随机访问迭代器
- 随机访问文件格式,用于分层组织的二进制文件和文本文件