9
votes

Obtenez l'index d'un STD :: élément vectoriel donné son adresse

Disons que j'ai un STD :: Vecteur et je reçois par une certaine signifie l'adresse de l'élément n-ème. Y a-t-il un moyen simple (plus rapide que d'itération via le vecteur) pour obtenir l'index à laquelle l'élément apparaît, étant donné l'adresse de base de mon std :: vecteur? Supposons que je suis sûr que l'élément est dans le vecteur.


0 commentaires

3 Réponses :


5
votes

distance (xxx.begin (), diitératif);

Ce qui précède ne fonctionnera que pour un vecteur :: Itérateur. Si vous n'avez qu'un pointeur brut sur un élément, vous devez l'utiliser de cette façon:

distance (& V [0], theelementptr);


5 commentaires

Il n'a pas d'itérateur, il a une adresse mémoire. Il n'y a aucune garantie que les itérateurs de vecteur sont des pointeurs bruts et, en fait, il y a plusieurs implémentations dans lesquelles elles ne sont pas.


Il y a une différence entre un pointeur et un itérateur, et il a spécifié un itérateur. C'est une bonne suggestion si s'il peut refroidir.


Pour un vecteur, un itérateur et un pointeur sont principalement interchangeables. La fonction de distance doit fonctionner si vous passez un pointeur d'élément au lieu d'un itérateur.


-1 Une adresse d'élément n'est pas un vecteur itérateur (en général, il peut être dans une certaine implémentation) cependant)


L'adresse d'un élément n'est pas techniquement un itérateur par type, mais un pointeur dans un vecteur a le comportement correct pour remplir un itérateur d'accès aléatoire. L'utilisation correcte de la distance dans ce cas serait la distance (& V [0], leelementptr) qui tombera à une soustraction conformément à la réponse ci-dessous.



18
votes

Puisque vous savez que l'élément est dans le vecteur, et vecteur garantit que son stockage est contigu, vous pouvez faire:

index = element_pointer - &vector[0];


12 commentaires

Remarque Ceci fonctionne uniquement sur C ++ 03 / C ++ 11 std :: vecteur s, et c ++ 11 std :: chaîne s


@Adrian, C ++ 98 ne garantit pas tout à fait que tous les éléments d'un vecteur résideront dans la mémoire contiguë. Pratiquement parlant, c'est sûr dans toutes les versions C ++, mais elle n'est garantie que par des révisions ultérieures de la norme.


C'est vrai, j'ajouterai ça.


Exclure le vecteur - en 23.1.1.12 où la sémantique opérationnelle d'un [n] est décrite - il en dit de la même chose que * (A.Begin () + N) pour vecteur et deque - cela doit garantir la mémoire contiguë pour les deux - n'est-ce pas? (Bien que ce n'est pas exactement l'anglais clair :-)


@Adrian Cornish: le C ++ 03 Spécialisé Vector n'est pas un conteneur, il ne remplit pas le concept. Depuis C ++ 11 Vecteur est un conteneur non décalable régulier.


D'accord, cela ne fonctionnera pas sur le vecteur . Vector était une si bonne idée ;-)


@MOOINGDUCK: Pas que vous n'êtes pas tort, mais que vous voyez comme c'est la fin de l'année 2011, est-ce vraiment pertinent? La norme de 2003 était il y a huit ans.


@GMAN: a une initialisation de la valeur mis en œuvre par SP ( Stackoverflow.com/Questtions/3931312/... )? C'est un exemple de compilateur présentant un comportement C ++ 98 au lieu de C ++ 03, bien que, bien entendu, il s'agit également d'un exemple d'engagement de MS à ne pas mettre en œuvre correctement C ++.


@Stevejessop: Cela viserait la peine de mentionner parce que un compilateur se trompe. Aucun compilateur traditionnel obtient cet aspect faux, alors pourquoi mentionner ses ancêtres? (Certes, je l'ai fait sonner comme l'âge est le seul facteur; je voulais dire qu'il devrait être pris en compte.)


@Gman: Je viens de dire cela comme exemple de montrer que l'âge de la norme n'a pas grand-chose à voir avec cela, car une fois qu'un compilateur décide qu'il ne se dérange pas avec des non-sens neufs comme C ++ 03 ou C99, Ensuite, cette décision peut entraîner un comportement de compilateur ancien pendant une très longue période. Mais comme exemple de cela, il a la faiblesse qu'il est difficile de dire la différence si la SP est délibérément conforme à l'ancienne standard, ou fait simplement quelque chose et découvre plus tard ce qu'elle est conforme à.


C'est-à-dire que je conviens que tout le monde a des vecteurs contigus. Je ne conviens pas que le fait qu'ils ont été standard pendant 8 ans a quelque chose à voir avec cela - je serais plutôt surpris s'il y avait un compilateur "important" qui avait des vecteurs non contigus au moment du vote du comité inclure l'exigence en C ++ 03. Le facteur important est que l'addition était non controversée, non pas que cela ait été fait il y a longtemps.


@Stevejessop: Je vois ce que tu veux dire, bien que je sent toujours que ça se fait il y a longtemps (pour une raison quelconque) suffit à mentionner que cela ne servira que de confondre et d'introduire des informations inutiles.



1
votes

Oui - Parce qu'un vecteur garantit que tous les éléments sont dans un bloc de mémoire contigu, vous pouvez utiliser le pointeur arithmétique pour la trouver comme si xxx


0 commentaires