Why can't I use the + = operator in a list iterator?

I have an iterator from std::list<std::string>

, but when I try to promote it with +=

, I get a compilation error.

Code:

#include <list>
#include <iostream>
#include <string>
int main() {
    std::list<std::string> x;

    x.push_front("British");
    x.push_back("character");
    x.push_front("Coding is unco");
    x.push_back("Society");
    x.push_back("City Hole");
    auto iter = x.begin();
    iter += 3;
    //std::advance(iter, 3);
    x.erase(iter);

    for (auto &e: x) {
        std::cout << e << "\n";
    }
}

      

If I compile this with clang++ -std=c++11 -o li li.cpp

I get:

li.cpp:13:10: error: no viable overloaded '+='
    iter += 3;
    ~~~~ ^  ~
1 error generated.

      

Why can't I use +=

with this iterator?

+3


source to share


3 answers


Iterator for std :: list BidirectionalIterator , which doesn't support operator+=

as RandomAccessIterator .

You can use operator++

which is supported by InputIterator (including BidirectionalIterator

) something like

++iter;
++iter;
++iter;

      

But this is ugly. The best way, as you commented, is using std :: advance (or std :: next (since C ++ 11)), which can be used with InputIterator (including BidirectionalIterator

) and also uses the functions it supports RandomAccessIterator

.

(emphasis mine)



Complexity

Linear.

However, if InputIt

additionally meets the requirements RandomAccessIterator

, the complexity is constant .

So you can just use it without considering the iterator category, std::advance

will make the best choice for you. eg.

std::advance(iter, 3);

      

or

iter = std::next(iter, 3);

      

+15


source


The reason is that the operator is +=

not defined for the bidirectional iterator you are using.

For all iterators, there are at least:

  • Copyable and destructible, i.e. X b(a);

    andb = a;

  • Can be increased, i.e. ++a

    anda++



Everything else depends on the type of iterator checking the table here :

enter image description here

As you can see, a random access iterator will do the trick.

+5


source


A is std::list::iterator

not a Random Iterator . It is not possible to "jump forward" multiple items in a list; you must iterate over the list until you reach the item you want. You can use std::advance

which will infer the best way to advance the iterator based on the category of the iterator. In case std::list::iterator

it will increment the iterator in the loop.

+3


source







All Articles