Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we increase an iterator multiple positions without the 'advance' function?

I know we can use advance() function to increment the iterator. We also use iterator++ to increase the iterator by one position. Why we cannot use it+=2?

int main()
{
    list<int> l1{1, 2, 3, 5, 6};
    list<int> l2{2, 6, 8};
    auto it = l1.begin();
    advance(it, 2);         //works
    it++;                   //works
    // it+=2;                  //not work
    l2.splice(l2.begin(), l1, it);

    for(int a: l2) cout<<a<<" ";
    cout<<endl;

    return 0;
}

You can run the above code here.

like image 293
Lusha Li Avatar asked Oct 26 '18 06:10

Lusha Li


2 Answers

operator += is only supported by RandomAccessIterator; note that it's supposed to have constant complexity.

The iterator of std::list is BidirectionalIterator, which doesn't support operator +=. (The iterator of std::vector and std::array is RandomAccessIterator.)

Note that both of them could be used with std::advance, when used for RandomAccessIterator complexity is constant; when used for other InputIterators (including BidirectionalIterator) complexity is linear. That means using std::advance is a good idea because it's more general and could take advantage of the benefit of RandomAccessIterator automatically.

like image 94
songyuanyao Avatar answered Sep 18 '22 05:09

songyuanyao


You cannot use += 2 with this iterator because in general case incrementing std::list<> iterator by an arbitrary value is a relatively inefficient operation. += is not defined for your iterator type specifically to prevent you from carelessly/unknowingly using this inefficient operation in your code. Instead, if you really want to do that you are supposed to use std::advance, which is a "red flag" function that is intended to highlight the fact that you are likely doing something inefficient. std::advance is mostly intended for code sketching or for unlikely-to-get-executed fallback code. You are not supposed to gratuitously use std::advance in production code. If you suddenly find yourself relying on std::advance, it means that you probably need to redesign your data structures. Basically, std::advance is like a cast - avoid it unless you have a very very very good reason to use it.

Alternatively, you can use std::next

it = std::next(it, 2);

This function is much easier to use than std::advance. By default this function is designed to advance the iterator by 1 step forward, but you can specify the second parameter to move it farther. Again, when the value of second parameter is non-constant and potentially large, it should be considered a "red flag" function. A constant value of 2 is definitely within acceptable bounds.

like image 27
AnT Avatar answered Sep 18 '22 05:09

AnT