2010-08-09 4 views
2

Fondamentalement, je veux inverser itération à travers 2 std :: vecteurs. une couche a un vecteur de formes.Inverser l'itération avec 2 boucles?

habituellement que je pouvais faire quelque chose comme ceci:

for(int i = 0; i < layers.size(); ++i) 
{ 
    for(int j = 0; j < layers[i].shapes.size(); ++j) 
    { 
     layers[i].shapes[j].dosomething(); 
    } 
} 

Cependant en ce moment, je dois inverser itérer à travers les vecteurs et ont donc besoin d'utiliser un itérateur inverse mais comment ce travail? Puisque les itérateurs en font un pour chacun, comment puis-je accéder à la forme actuelle de la couche en cours d'itération? Merci

Répondre

5

La façon facile:

for(int i = layers.size() - 1; i >= 0; --i) 
{ 
    for(int j = layers[i].shapes.size() - 1; j >= 0; --j) 
    { 
     layers[i].shapes[j].dosomething(); 
    } 
} 

La façon "correcte":

for(vector<Layer>::reverse_iterator i = layers.rbegin(); i != layers.rend(); ++i) 
{ 
    for(vector<Shape>::reverse_iterator j = i->shapes.rbegin(); j != i->shapes.rend(); ++j) 
    { 
     j->dosomething(); 
    } 
} 
+0

Non, avec std :: les vecteurs, cela va sauter un élément – jmasterx

+0

@Jex: non, il ne sera pas – sje397

+0

'rbegin' renvoie un' reverse_iterator' – Naveen

0

Si vous utilisez des indices pour l'itération en avant pourquoi pas? Inverse

for(int i = layers.size()-1; i>=0; --i) 
0

Vous n'avez pas vraiment besoin d'itérateurs (inverses ou non) pour cela. Si vous aimez le code que vous avez en ce moment, et que vous voulez juste à courir en sens inverse, vous pouvez le faire assez directement:

for (int i=layers.size()-1; i>-1; --i) 
    for (int j=layers[i].shapes.size()-1; j>-1; --j) 
     layers[i].shapes[j].dosomething(); 

Bien sûr, vous pouvez utiliser itérateurs si vous préférez, mais dans ce cas Je pense que ça va rendre le code plus et dans l'ensemble plus complexe, sans ajouter beaucoup:

std::vector<shape>::reverse_iterator this_shape; 
std::vector<layer>::reverse_iterator this_layer; 

for (this_layer = layers.rbegin(); this_layer != layers.rend(); ++this_layer) 
    for (this_shape = this_layer->shapes.rbegin(); this_shape != this_layer->shapes.rend(); ++this_shape) 
     this_shape->dosomething(); 
0
for(std::vector<mytype>::reverse_iterator i = layers.rbegin(); i != layers.rend(); ++i) 
{ 
    for(std::vector<myothertype>::reverse_iterator j = i->shapes.rbegin(); j != i->shapes.rend(); ++j) 
    { 
     j->dosomething(); 
    } 
} 

itérateurs sont plus souples ainsi que indicielle - il est beaucoup plus simple de changer commencer/rbegin, fin/rend, et reverse_iterator/itérateur, pour changer l'itérateur direction des ions. Cela devient encore plus facile si vous utilisez ce code souvent et pouvez juste coller un typedef quelque part pour cela et certainement mieux si vous avez C++ 0x ou pouvez utiliser une fonction en ligne pour la déduction de type automatique.

0

Vous pouvez également utiliser des itérateurs inversés, mais cela devient un peu bavard. Si vous avez Boost, cependant, il est vraiment facile que vous pouvez faire quelque chose comme:

BOOST_REVERSE_FOREACH(std::vector<Shape>& layer, layers) 
{ 
    BOOST_REVERSE_FOREACH(Shape& shape, layer) 
    { 
    shape.dosomething(); 
    } 
} 
0

itérateurs aux conteneurs vous permettent d'accéder à l'objet « courant » en utilisant le * ou -> opérateurs - en ce que itérateurs sens sont comme des pointeurs sur les éléments du vecteur.

Par exemple, si iter est un itérateur sur un vecteur de couches, vous pouvez accéder à la couche actuellement pointée par l'itérateur en utilisant:

layer = *(iter); 

ou

nshapes = iter->shapes.size(); 
1

utilisation inverse itérateurs.

typedef std::vector::<Layer>::reverse_iterator LayerIt; 
for(LayerIt layerIt = layers.rbegin(); layerIt != layers.rend(); ++layerIt) // reverse-iterator 
{ 
    Layer& layer = *layerIt; 

    typedef std::vector<Shape>::reverse_iterator ShapeIt; 
    std::vector<Shape>& shapes = layer.shapes; 

    for(ShapeIt shapeIt = shapes.rbegin(); shapeIt != shapes.rend(); ++shapeIt) // reverse-iterator 
    { 
    Shape& shape = *shapeIt; 
    shape.dosomething(); 
    } 
} 

std :: vecteur de la rbegin() et Pourfendre(): http://www.cplusplus.com/reference/stl/vector/ Je décomposées le code pour le rendre plus évident, dites-moi si ce n'est pas.Si vous ne connaissez pas itérateurs, vous devez rechercher :)

Notez que si vous utilisez un compilateur récent avec les nouvelles fonctionnalités auto, il est plus simple d'écrire:

for(auto layerIt = layers.rbegin(); layerIt != layers.rend(); ++layerIt) // reverse-iterator 
{ 
    Layer& layer = *layerIt; 
    std::vector<Shape>& shapes = layer.shapes; 

    for(auto shapeIt = shapes.rbegin(); shapeIt != shapes.rend(); ++shapeIt) // reverse-iterator 
    { 
    Shape& shape = *shapeIt; 
    shape.dosomething(); 
    } 
} 
+0

Cela devrait être «reverse_iterator» ne devrait-il pas? – sje397

+0

Oui, réparé maintenant. – Klaim