Testing whether an iterator points to the last item?

前端 未结 9 921
旧巷少年郎
旧巷少年郎 2020-12-23 11:31

I have an stl iterator resulting from a std::find() and wish to test whether it is the last element. One way to write this is as follows:

mine *match = some         


        
9条回答
  •  独厮守ぢ
    2020-12-23 12:30

    You would first need a way to determine if an iterator is a reverse one, which was ingeniously shown here :

    #include 
    #include 
    
    template
    struct is_reverse_iterator : std::false_type { };
    
    template
    struct is_reverse_iterator>
    : std::integral_constant::value>
    { };
    

    Then you could have two flavors for performing the test

    template // for normal iterators
    struct is_last_it
    {
        template
        static bool apply(It it, Cont const &cont)
        { // you need to test with .end()
            return it != cont.end() && ++it == cont.end();
        }
    };
    
    template<> // for reverse iterators
    struct is_last_it
    {
        template
        static bool apply(It it, Cont const &cont)
        { // you need to test with .rend()
            return it != cont.rend() && ++it == cont.rend();
        }
    };
    

    And a single interface function

    template
    bool is_last_iterator(It it, Cont const &cont)
    {
        return is_last_it::value>::apply(it, cont);
    };
    

    Then for every type of iterator (reverse / straight) you can use the interface function

    int main()
    {
        std::vector v;
        v.push_back(1);
    
        auto it (v.begin()),  ite(v.end());   // normal iterators
        auto rit(v.rbegin()), rite(v.rend()); // reverse iterators
    
        std::cout << is_last_iterator(it, v) << std::endl;
        std::cout << is_last_iterator(ite, v) << std::endl;
        std::cout << is_last_iterator(rit, v) << std::endl;
        std::cout << is_last_iterator(rite, v) << std::endl;
    
        return 0;
    }
    

    Note that some implementation (apart from std::begin() and std::end() which are common enough, also include std::rbegin() and std::rend(). When possible use this set of functions instead of member .begin() etc.

提交回复
热议问题