为了练习和理解,我重新发明了STL vector。当然,我还必须实现一个迭代器系统。为了重用,我希望实现所有具有继承性的迭代器类别(例如:class random_access_iterator : public bidirectional_iterator<T, Container>
)。
现在我遇到了一个大问题。考虑以下片段:
custom_vector<int>::iterator it_start = container.begin(), it_end = container.end();
custom_vector<int> other_container(it_start, --(--it_end));
因为递减操作符有类别双向迭代器,所以我也在那里实现了它。
template <class T, class Container>
class bidirectional_iterator : public forward_iterator<T, Container>
{
// ...
public:
/* Decrement Operators */
bidirectional_iterator &operator--() { /* code */ }
bidirectional_iterator operator--(int) { /* code */ }
// ...
}
考虑到这一点,下面的代码将无法工作,因为第一个参数将是random_access_iterator
类型,第二个参数将是bidirectional_iterator
类型。
custom_vector<int> other_container(it_start, --(--it_end));
由于构造函数具有两种不同的迭代器类型是没有意义的(而且STL Vector也没有这样的构造函数),所以我不会实现这样的构造函数,这会导致编译错误。
error: no matching constructor for initialization of 'custom_vector<int>'
custom_vector<int> other_container(it_start, --(--it_end));
^ ~~~~~~~~~~~~~~~~~~~~~~
candidate constructor not viable: no known conversion from 'custom_vector<int>::iterator' (aka 'random_access_iterator<int, custom_vector<int> >') to 'custom_vector<int>::size_type' (aka 'unsigned long') for 1st argument
explicit custom_vector(size_type n, const value_type &val = value_type(), const allocator_type &alloc = allocator_type()) : _capacity(n), _alloc(alloc)
^
note: candidate template ignored: deduced conflicting types for parameter 'InputIterator' ('random_access_iterator<int, custom_vector<int> >' vs. 'bidirectional_iterator<int, custom_vector<int> >')
custom_vector(InputIterator first, InputIterator last, const allocator_type &alloc = allocator_type(),
^
note: candidate constructor not viable: allows at most single argument 'alloc', but 2 arguments were provided
explicit custom_vector(const allocator_type &alloc = allocator_type()) : _capacity(), _alloc(alloc), _content() {}
^
note: candidate constructor not viable: requires single argument 'x', but 2 arguments were provided
custom_vector(const custom_vector &x) : _capacity(x.capacity()), _alloc(x.get_allocator()), _content()
^
1 error generated.
1.我的继承迭代器实现是正确的吗?坚持这个实现有意义吗?还是只为每个容器实现一个特定的迭代器更好?
1.有没有一种方法可以实现一个“迭代器转换器”,在需要的时候自动地把我的bidirectional_iterator转换成random_access_iterator?
2条答案
按热度按时间zxlwwiss1#
我的继承迭代器实现正确吗?
不可以。C++的迭代器不使用继承,它使用concepts。如果一个类型提供了随机访问迭代器方法(
[]
,+
,-
等),那么它就是std::random_access_iterator
。这包括指针类型,它们不能从某个基类继承。每个容器的迭代器都是特定于该容器的。不同类别的存在是因为一些操作不能(有效地)为那些容器实现。
o0lyfsai2#
我相信已经太晚了,但我还是会尝试回答你。我认为你的实现有点太复杂了,我不相信继承是实现不同迭代器的好方法。而且,迭代器可以提供的访问类型与它的实现无关(
std::vector
和std::deque
容器都支持随机访问,但是双端队列不保证存储器中的连续性,并且期望特定的实现通过索引来访问各个元素)。另一方面,基于内存模型创建泛型迭代器是一个有趣的想法,它允许一定的灵活性和健壮性。您可以基于使用迭代器的数据结构来实现迭代器,将它们划分如下:数组迭代器、反队列迭代器、前向列表迭代器、列表迭代器、二叉树迭代器。
基本实现可以如下: