3

我想改进基于范围的 for 循环,例如通过启用反向迭代。通过编写适配器,我设法让它在某种程度上工作,但我不知道如何使适配器可组合。

#include <iostream>
template <typename IT> struct reversed_range {
        struct reversed_iterator {
            IT it;
            reversed_iterator(IT it): it(it){}
            reversed_iterator& operator++(){
                --it;
                return (*this);
            }
            typename std::iterator_traits<IT>::reference operator*(){
                IT tmp = it;
                --tmp;
                return *tmp;
            }
            bool operator==(const reversed_iterator& other) const {
                return it == other.it;
            }
            bool operator!=(const reversed_iterator& other) const { 
                return !(*this == other);
            }
        };
        IT itbegin;
        IT itend;
        reversed_range(const IT& b,const IT& e): itbegin(b),itend(e){}
        reversed_iterator begin() const { return reversed_iterator(itend); }
        reversed_iterator end() const { return reversed_iterator(itbegin); }
    };
    template <typename IT>
    reversed_range<IT> reverse_range(const IT& begin,const IT& end) { 
        return reversed_range<IT>(begin,end); 
    }
    template <typename C>
    reversed_range<C> reverse_range(const C& c) {
        return reversed_range<typename C::iterator>(std::begin(c),std::end(c));
    }

int main() {
    int x[] = {1,2,3,4,5};
    for (auto y : reverse_range(std::begin(x),std::end(x))){
        std::cout << y << "\t";
    }
    for (auto y : reverse_range(reverse_range(std::begin(x),std::end(x)))){
        std::cout << y << "\t";
    }
    return 0;
}

第一个循环就像一个魅力,但第二个我得到了错误:

error: no type named ‘reference’ in ‘struct std::iterator_traits<reversed_range<int*> >’
             typename std::iterator_traits<IT>::reference operator*(){
                                                          ^~~~~~~~

我知道为什么会发生这种情况,并且我知道如何针对这种特殊情况解决它。但是,如果我正确理解这个答案,我将不得不专门iterator_traits针对我的每个可能的实例化,reversed_iterator这实际上并不可行。我有点迷茫,大多数时候我写自己的迭代器我发现自己写了很多样板,只是为了达到我意识到我需要成倍增加的样板才能让它工作的地步。我的意思是我什至没有开始考虑const_iterators。

有没有办法让上述工作(而不必专门iterator_traits针对iterator我想要逆转的每一个?

PS:标记为 C++11,因为那是我当前的范围,但如果对此有改进,我不介意使用更新的标准。

4

1 回答 1

4

std::iterator_traits<Iterator>::something只是Iterator::something默认情况下。因此,只需将 typedef 添加到您的reversed_iterator类型中:

struct reversed_iterator {
    using difference_type = typename std::iterator_traits<IT>::difference_type;
    using value_type = typename std::iterator_traits<IT>::value_type;
    using pointer = typename std::iterator_traits<IT>::pointer;
    using reference = typename std::iterator_traits<IT>::reference;
    using iterator_category = /* appropriate category */;

    // ...
};
于 2018-05-23T19:43:29.167 回答