How to increment an iterator by 2?

前端 未结 8 1695
眼角桃花
眼角桃花 2020-12-04 16:16

Can anybody tell me how to increment the iterator by 2?

iter++ is available - do I have to do iter+2? How can I achieve this?

相关标签:
8条回答
  • 2020-12-04 16:38

    Assuming list size may not be an even multiple of step you must guard against overflow:

    static constexpr auto step = 2;
    
    // Guard against invalid initial iterator.
    if (!list.empty())
    {
        for (auto it = list.begin(); /*nothing here*/; std::advance(it, step))
        {
            // do stuff...
    
            // Guard against advance past end of iterator.
            if (std::distance(it, list.end()) > step)
                break;
        }
    }
    

    Depending on the collection implementation, the distance computation may be very slow. Below is optimal and more readable. The closure could be changed to a utility template with the list end value passed by const reference:

    const auto advance = [&](list_type::iterator& it, size_t step)
    {
        for (size_t i = 0; it != list.end() && i < step; std::next(it), ++i);
    };
    
    static constexpr auto step = 2;
    
    for (auto it = list.begin(); it != list.end(); advance(it, step))
    {
        // do stuff...
    }
    

    If there is no looping:

    static constexpr auto step = 2;
    auto it = list.begin();
    
    if (step <= list.size())
    {
        std::advance(it, step);
    }
    
    0 讨论(0)
  • 2020-12-04 16:43

    You could use the 'assignment by addition' operator

    iter += 2;
    
    0 讨论(0)
  • 2020-12-04 16:44

    http://www.cplusplus.com/reference/std/iterator/advance/

    std::advance(it,n);
    

    where n is 2 in your case.

    The beauty of this function is, that If "it" is an random access iterator, the fast

    it += n
    

    operation is used (i.e. vector<,,>::iterator). Otherwise its rendered to

    for(int i = 0; i < n; i++)
        ++it;
    

    (i.e. list<..>::iterator)

    0 讨论(0)
  • 2020-12-04 16:51

    If you don't have a modifiable lvalue of an iterator, or it is desired to get a copy of a given iterator (leaving the original one unchanged), then C++11 comes with new helper functions - std::next / std::prev:

    std::next(iter, 2);          // returns a copy of iter incremented by 2
    std::next(std::begin(v), 2); // returns a copy of begin(v) incremented by 2
    std::prev(iter, 2);          // returns a copy of iter decremented by 2
    
    0 讨论(0)
  • 2020-12-04 16:51

    We can use both std::advance as well as std::next, but there's a difference between the two.

    advance modifies its argument and returns nothing. So it can be used as:

    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    auto itr = v.begin();
    advance(itr, 1);          //modifies the itr
    cout << *itr<<endl        //prints 2
    

    next returns a modified copy of the iterator:

    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    cout << *next(v.begin(), 1) << endl;    //prints 2
    
    0 讨论(0)
  • 2020-12-04 16:52

    The very simple answer:

    ++++iter
    

    The long answer:

    You really should get used to writing ++iter instead of iter++. The latter must return (a copy of) the old value, which is different from the new value; this takes time and space.

    Note that prefix increment (++iter) takes an lvalue and returns an lvalue, whereas postfix increment (iter++) takes an lvalue and returns an rvalue.

    0 讨论(0)
提交回复
热议问题