11
votes

Conversion d'un vecteur à un tableau - Y a-t-il un moyen «standard» de faire cela?

Je sais que vous pouvez simplement faire: & thevector [0] , mais cette norme est-elle? Est ce comportement toujours garanti?

Si non, y a-t-il un moyen meilleur et moins "pirateux" de faire cela?


4 commentaires

En C ++ 11, la manière appropriée est thevector.data () .


Notez que & theVector [0] ne donne pas un tableau , mais plutôt un pointeur . Pointeurs et tableaux sont des choses différentes dans la langue, avec différents types. Vous ne pouvez pas convert un vecteur à un tableau de quelque manière standard, bien que votre approche est un moyen standard d'obtenir un pointeur aux données.


Je n'appellerais pas que ce piratage pirate comme la compatibilité avec c API utilise des pointeurs de tableau était une décision de conception dans la STL. L'alternative, qui est parfois vue et * thevector.begine (), ne doit pas être utilisée.


@Aselle: & * thevector.begin () n'est pas meilleur ni pire que & thevector [0] tant que THEVector n'est pas un std :: vecteur .


4 Réponses :


20
votes

Oui, ce comportement est garanti. Bien que je ne puisse pas le citer, la standard garantit que les éléments de vecteur sont stockés consécutivement en mémoire pour permettre cela.

Il y a une exception si:

Il ne fonctionnera pas pour vecteur en raison d'une spécialisation de modèle.

http://fr.wikipedia.org/wiki / Séquence_Container_% 28c% 2b% 2b% 29 # Spécialisation_for_bool

Cette spécialisation tente de sauvegarder la mémoire en emballant bools ensemble dans un champ de bit. Cependant, il casse une certaine sémantique et, en tant que tel, & thevector [0] sur un vecteur ne fonctionnera pas.

Dans tous les cas, vecteur est largement considéré comme une erreur < / a> La variante est donc d'utiliser std :: deque à la place.


8 commentaires

Je suppose que dans ce cas, je devrais simplement le copier sur l'utilisation de copier ou quelque chose?


Il y a une autre exception: si le vecteur est vide, vous ne pouvez pas utiliser l'opérateur de l'indice.


@Jonathanlingle oui, vous pouvez utiliser std :: copy (copy () pour le faire.


@ DietMarkühl Ah, oui, bien sûr ... puisque vous ne seriez pas en mesure de Thevector [0] en premier lieu. XD


Juste un autre commentaire aléatoire: en C ++ 2011 STD :: Vector a des membres de données () renvoyant un pointeur sur le premier élément. Cela fonctionne également pour les vecteurs vides


Si le vecteur est vide, c'est & thevector [0] ? C'est sûrement? Bien sûr, cela ne peut pas être déréférencé. Mais je pense toujours / espérons qu'il est défini et est égal à (t *) thevector.begin () . Quoi qu'il en soit, peut-être que la solution à tout cela est d'utiliser (+ thevector.begin ()) à la place - une addition unaire convertit les choses aux pointeurs, IIRC.


@AARONMCDAID: Point 1: & THEVector [0] est un comportement non défini lorsque thevector.size () == 0 . Cela signifie qu'il est défini à rien. Dans la pratique, vous pourriez obtenir, mais les optimiseurs d'un compilateur peuvent également jouer à Havoc avec votre code. Point 2: Les itérateurs ne sont pas tenus de supporter UNIA +, il n'ya donc aucune garantie que cela fait ce que vous voulez, ou quoi que ce soit du tout. Point 3: La bonne façon d'accéder aux données sous-jacentes est actuellement thevector.data () . Vous obtiendrez également une belle erreur de compilateur si vous utilisez std :: vecteur :: données () , car le tableau sous-jacent n'existe pas.


(Supprimer et remplacer mon propre commentaire) Je pensais en quelque sorte que les itérateurs ont un opérateur de conversion pour les pointeurs, mais je me trompe. Maintenant, je suis vraiment confus sur ce qu'il faut faire si le vecteur est vide et que vous n'avez pas .data () (parce que vous êtes pré-C ++ 11)



0
votes

2 commentaires

INT Array [Vec.Size ()]; n'est pas légal C ++.


Magic_Number Le codage est techniquement légal, mais une très mauvaise chose. Ce n'est pas mieux.



13
votes

C ++ 11 fournit la méthode () code> sur std :: vecteur code> qui renvoie un t * code>. Cela vous permet de faire:

#include <iostream>
#include <vector>

int main()
{
  std::vector<int> vector = {1,2,3,4,5};
  int* array = vector.data();

  vector.resize(100); //This will reserve more memory and move the internal array

  //This _may_ end up taking the place of the old array      
  std::vector<int> other = {6,7,8,9,10}; 

  std::cout << array[4] << std::endl; //_May_ now print '10'
}


0 commentaires

1
votes

Nous pouvons faire cela à l'aide de la méthode Data (). C ++ 11 fournit cette méthode. Il renvoie un pointeur sur le premier élément du vecteur. Vecteur même s'il est vide, nous pouvons appeler cette fonction elle-même sans problèmes xxx


0 commentaires