2 votes

Comment redimensionner un std::vector sans perdre les données existantes ?

J'ai implémenté un algorithme qui nécessite que je retire et ajoute les mêmes éléments d'un vecteur à chaque itération d'une boucle.

Exemple :

itération 1 : |1 2 3 4| (taille 4)

itération 2 : |1 3| 2 4 (taille 2 avec les éléments '2' et '4' toujours présents en mémoire mais non comptabilisés dans la taille du vecteur)

itération 3 : |1 2 3| 4 (taille 3 avec l'élément '4' toujours présent)

En gros, je veux pouvoir modifier la valeur renvoyée par la fonction size() sans affecter le vecteur pour des raisons de performances.

Je sais que je pourrais utiliser une autre variable en dehors de mon vecteur pour garder la trace de sa taille, mais je voulais savoir si cela était possible directement en interne dans le conteneur std::vector.

Merci pour toute aide.

7voto

Nicol Bolas Points 133791

Ce que vous voulez est logiquement incompatible avec la façon dont vector travaux. size renvoie le nombre d'objets de type T dans le vector . En réduisant cette taille, tous les objets coupés à l'extrémité sont détruits. Lorsque vous augmentez la taille, vous ajoutez nouveaux objets .

Il serait préférable de construire un type autour de vector qui a le comportement que vous voulez.

3voto

Peter Points 4026

Vous ne pouvez pas faire ça.

La seule façon de réduire la valeur déclarée par size() est de redimensionner. Lorsque le redimensionnement réduit la taille, les éléments situés en dehors de la nouvelle taille n'existent plus en ce qui concerne le programme. Tout moyen d'y accéder (ou d'y réaccéder, dans votre cas) entraîne un comportement indéfini.

Si vous voulez suivre le nombre d'éléments d'un tableau en cours d'utilisation (disons que vous utilisez deux éléments d'un vecteur à cinq éléments), créez une variable supplémentaire pour en tenir compte. Cette variable devra être maintenue cohérente avec la taille du vecteur (par exemple, pour éviter de suivre que dix éléments sont utilisés dans un vecteur de cinq éléments).

Si vous voulez conserver la variable avec le vecteur, faites en sorte qu'ils soient tous deux membres d'un groupe struct / class type. Cette classe peut fournir des fonctions membres ou des opérations qui gèrent à la fois le vecteur et le nombre d'éléments "utilisés", afin d'assurer la cohérence.

3voto

Adrian Colomitchi Points 3626

Je ne sais pas, peut-être utiliser has-a au lieu de is-a ?

template <typename T> class subvector {
protected:
  std::vector<T> owner_;
  std::size_t    begin_;
  std::size_t    end_;
public:
  subvector(std::vector<T>& owner, size_t from, size_t to) :
    owner_(owner), begin_(from), end_(to)
  {
     // do some range checks
  }

  size_t size() const {
    // range check before return
    // either throw (fast-fail) *or* 
    //   adjust the out-of-range ends (lenient but maybe unsafe)
    return end_-begin_+1;
  }
  // implement as many of the std::vector methods/operators
  // you are likely to need in your code by delegation
  // to the owner_.
  // Stay minimal, whenever you use something you don't have, 
  // the compiler will tell you.
};

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X