jwi*_*ley 5 c++ iterator stl c++11
对于使用STL函数遍历一个C阵列中,std::begin和std::end功能是很方便的等同物.begin()和.end().但是,对于双向C++容器,没有std::rbegin和std::rend等价的反向迭代器.这样的等价物是否存在于其他名称之下,或者是否易于制作?我意识到一个难点是std::begin通常返回一个原始指针,而对于相反的情况,这需要一个包装器,以便++操作可以重载.可能看起来非常不完整
template<class T>
class ReverseArrayIterator {
public:
ReverseArrayIterator(T* ptr) : _ptr(ptr) {}
operator T*() {
return _ptr;
}
void operator++() {
--_ptr;
}
T operator*() {
return *_ptr;
}
bool operator!= (ReverseArrayIterator& rhs) {
return _ptr != rhs._ptr;
}
private:
T* _ptr;
};
template<class T, size_t size>
ReverseArrayIterator<T> rbegin(T (&array)[size]) {
return ReverseArrayIterator<T>(&array[0] + size - 1);
}
template<class T, size_t size>
ReverseArrayIterator<T> rend(T (&array)[size]) {
return ReverseArrayIterator<T>(&array[0] - 1);
}
Run Code Online (Sandbox Code Playgroud)
我使用以下代码测试了这个简单的实现:
int x[] = {1,2,3,4,5,6,0,0,0,10,11,12};
auto a = std::find(std::begin(x),std::end(x),0);
auto b = std::find(rbegin(x),rend(x),0);
cout << std::distance(x,a) << endl;
cout << std::distance(x,(int*)b) << endl;
Run Code Online (Sandbox Code Playgroud)
这可以充当C阵列的完全可操作的反向迭代器类,还是会遇到更多障碍?一个可能的障碍似乎是隐式转换为原始指针,我希望它可以用在像std :: distance这样的函数中 - 上面的代码片段不会编译std::distance(x,b)(或类似函数,可能),但需要手动转换(int*).
(我正在将这些评论转化为帮助他人的答案。感谢chris和StoryTeller。)
从C++14开始,就像您所描述的那样,有rbegin()和rend() 。
还有一个适配器类可将(正向)迭代器转换为反向迭代器。请注意,应将正向 begin()迭代器传递给make_reverse_iterator反向迭代器,反之亦然:
std::vector<int> v{ 1, 3, 10, 8, 22 };
std::copy(
std::make_reverse_iterator(v.end()),
std::make_reverse_iterator(v.begin()),
std::ostream_iterator<int>(std::cout, ", "));
Run Code Online (Sandbox Code Playgroud)