J'ai un itérateur d'un std::list<std::string>, mais quand j'essaye de l'avancer en utilisant +=, j'obtiens une erreur de compilation.

Le code est:

#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";
    }
}

Si je compile ceci en utilisant clang++ -std=c++11 -o li li.cpp, j'obtiens:

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

Pourquoi ne puis-je pas utiliser += avec cet itérateur?

3
KiYugadgeter 26 avril 2017 à 17:52

2 réponses

Un std::list::iterator n'est pas un Random Access Iterator. Il n'est pas possible de "sauter" plusieurs éléments dans une liste, vous devez parcourir la liste jusqu'à ce que vous atteigniez l'élément souhaité. Vous pouvez utiliser std::advance qui en déduira la meilleure façon d'avancer l'itérateur basé sur la catégorie d'itérateur. Dans le cas d'un std::list::iterator, il incrémentera l'itérateur dans une boucle.

3
François Andrieux 26 avril 2017 à 14:55

La raison est simplement que l'opérateur += n'est pas défini pour l'itérateur bidirectionnel que vous utilisez.

Pour tous les itérateurs, il y a au moins:

  • Copiable et destructible, c'est-à-dire X b(a); et b = a;
  • Peut être incrémenté, c'est-à-dire ++a et a++

Tout le reste dépend du type d'itérateur, consultez le tableau ici:

enter image description here

Comme vous le voyez, un itérateur à accès aléatoire ferait l'affaire.

5
Pete Becker 26 avril 2017 à 16:03