11
votes

Iterating sur 2 dimensions vecteur stl c ++

Je tente actuellement d'imprimer une histoire de mouvements pour les joueurs dans un jeu que je travaille. À la fin de chaque tour, chaque joueur a déplacé une certaine quantité dans la direction positive ou négative et celle-ci est enregistrée comme in int dans le vecteur de mouvement. Finalement, je souhaite tracer les instructions déplacées contre chaque joueur, mais j'ai du mal à extraire les données du vecteur 2D.

La première chose que j'ai essayée était de simplement itérité et d'imprimer tous les éléments, cependant Cela ne compile pas: xxx

Le compilateur donne ce message d'erreur que je ne comprends pas vraiment: xxx

Toute aide est grandement appréciée!


0 commentaires

5 Réponses :


4
votes

const code> Objets renvoiez const_iterators code>, donc simplement remplacer itérateur code> par const_iterator code> partout. Cela empêche également les modifications non désirées des vecteurs.

Il s'agit de la combinaison des suggestions de Sam et de Mathieu: P>

#include <ostream>
#include <vector>

typedef std::vector<int> Vector;
typedef std::vector<Vector> DoubleVector;


template<typename Char, typename Traits>
std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& stream,
           const DoubleVector& movement) {
    for (DoubleVector::const_iterator row = movement.begin(); row != movement.end(); ++row) {
         for (Vector::const_iterator col = row->begin(); col != row->end(); ++col) {
            stream << *col;
         }
    }
return stream;
}


0 commentaires

12
votes

Le 2D Vecteur est déclaré const , vous devez donc utiliser const_iterator au lieu de itérateur .

Vous ne devez pas non plus déléguer col . C'est un itérateur, vous n'avez donc besoin que d'une désarence une fois. xxx


0 commentaires

16
votes

Vous devez utiliser un const_iterator code> si le vecteur code> code> est une référence de const. Aussi, pour générer col code>, vous n'avez besoin que de la désarférence une fois.

typedef std::vector<int> Vector;
typedef std::vector<Vector> DoubleVector;

void output_movement(
    const DoubleVector& movement
)
{
    for (DoubleVector::const_iterator row = movement.begin(); row != movement.end(); ++row) {
         for (Vector::const_iterator col = row->begin(); col != row->end(); ++col) {
            std::cout << *col;
         }
         std::cout << std::endl;
    }
}


3 commentaires

Je dirais que si vous voulez réécrire le code, il pourrait être utile de mettre également correctement la mise correctement rangée et COL DÉCLARATIONS DANS LE pour boucle pour un décodage approprié.


De plus, il serait peut-être un peu plus c ++ - comme si sortie_movement a été appelé opérateur <<< / code>.


@Philipp: Je ne suis pas sûr. L'opérateur de surcharge est toujours délicat, surtout quand il pourrait y avoir plusieurs affichages possibles.



0
votes

omg, n'importe quoi em> est meilleur que ce désordre de pour code> boucles. Ici quelques alternatives. Choisissez que vous voulez. XXX PRE>

ou, P>

void output_movement (const VVI & m) {
    foreach (const VI& v, m)
        foreach (int i, v)
            cout << i;
}


0 commentaires

3
votes

John, vous avez suggéré d'utiliser Lambdas, mais si C ++ 11 est disponible, je préférerais

for (auto& row : movement) {
     for (auto& elem : row) {
        std::cout << elem;
     }
}


3 commentaires

+1 pour les boucles de plage propre - Bien qu'il n'y ait pas besoin de "&", est là?


Christian: Oui, il y a! Sinon, chaque rangée sera copiée et itératée sur. La deuxième référence n'est pas aussi cruciale.


Ben: Oh, ça: Oui, certainement. Mais alors vous pourriez aussi bien écrire const auto & pour vous assurer de ne pas modifier accidentellement votre référence s ou elem elem