如何解决STL 容器中的迭代器实现
template <typename T>
struct ArrayIterator {
using value_type = typename T::value_type;
using pointer = value_type*;
using reference = value_type&;
using self = ArrayIterator;
pointer ptr;
ArrayIterator() : ptr{nullptr} {}
ArrayIterator(pointer ptr) : ptr{ptr} {}
reference operator*() {
return *ptr;
}
bool operator==(self const& other) const {
return ptr == other.ptr;
}
bool operator!=(self const& other) const {
return !(*this == other);
}
self operator++() {
++ptr;
return *this;
}
self operator++(int) {
auto copy = *this;
++ptr;
return copy;
}
};
template <typename T,size_t size>
struct Array {
T arr[size];
using value_type = T;
using iterator = ArrayIterator<Array<T,size>>;
iterator begin() {
return iterator(arr);
}
Array() : arr{1,3,4,22,3} {}
iterator end() {
return iterator(arr + size);
}
};
int main() {
using array = Array<int,5>;
array arr;
}
假设一切都是公开的,我们只传递 int
作为类型参数,并且数组具有默认构造函数只是为了测试基于范围的 for
循环。它有效。
我的问题是,为什么我们不能使用继承?像这样:
template <typename T,size_t size>
struct Array : ArrayIterator<Array<T,size>> {}
如果使用,我得到以下错误(编译器是 clang 11):
first.cpp:46:34: error: no type named 'value_type' in 'Array<int,5>'
using value_type = typename T::value_type;
~~~~~~~~~~~~^~~~~~~~~~
first.cpp:82:16: note: in instantiation of template class 'ArrayIterator<Array<int,5>>' requested here
struct Array : ArrayIterator<Array<T,size>> {
^
first.cpp:101:9: note: in instantiation of template class 'Array<int,5>' requested here
array arr;
^
1 error generated
我无法理解发生了什么。
解决方法
您不能随意使用继承,因为如果您尝试,代码将有一个 catch-22。 ArrayIterator
将尝试将其 value_type
定义为数组 value_type
的别名,然后后者尚未定义。这就是您收到编译器错误的原因。
您的迭代器不需要访问 Array
类本身,因此将 Array
类类型传递给迭代器的模板参数是没有意义的。只需传递数组的 value_type
而不是 Array
本身,并将迭代器的 value_type
更改为只是 T
而不是 typename T::value_type
:
template <typename T>
struct ArrayIterator {
using value_type = T;
using pointer = value_type*;
using reference = value_type&;
using self = ArrayIterator;
pointer ptr;
ArrayIterator() : ptr{nullptr} {}
ArrayIterator(pointer ptr) : ptr{ptr} {}
reference operator*() {
return *ptr;
}
bool operator==(self const& other) const {
return ptr == other.ptr;
}
bool operator!=(self const& other) const {
return ptr != other.ptr;
}
self& operator++() {
++ptr;
return *this;
}
self operator++(int) {
auto copy = *this;
++ptr;
return copy;
}
};
template <typename T,size_t size>
struct Array {
using value_type = T;
using iterator = ArrayIterator<T>;
T arr[size];
iterator begin() {
return iterator(arr);
}
iterator end() {
return iterator(arr + size);
}
};
int main() {
using array = Array<int,5>;
array arr{1,3,4,22,3};
for (auto val : arr) {
cout << val << endl;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。