31 votes

Moins universel <> pour les pointeurs en standard C ++

Combien de fois j'ai besoin d'un ensemble de pointeurs. Chaque fois que cela arrive, j'arrive à la fin de l'écriture d'un moins<> la mise en œuvre d'un pointeur de type - cast deux pointeurs vers size_t et de comparer les résultats.

Ma question est, est ce qui est disponible dans la norme? Je ne pouvais pas trouver quoi que ce soit. Semble assez de cas...

Mise à jour: il semble que la norme à venir résout tous les problèmes avec moins de<> condition pour les types pointeur et unordered_set inclus, trop. Dans quelques années, cette question sera discutable.

Dans le même temps, la norme actuelle n'a pas de "juridique" solution à cela, mais size_t cast fonctionne.

Mise à jour pour mettre à jour: bien, je vais être sur le cul! Non seulement

std::map<void *, int, std::less<void*> > myMap;

fonctionne, mais même

std::map<void *, int > myMap;

ainsi.

Et c'est dans gcc 3.4.1 . J'ai fait tous ces moulages pour rien, et litb est parfaitement droit. Même le numéro de l'article, il cite le cas est exactement le même dans la norme actuelle. Hourra!

31voto

Johannes Schaub - litb Points 256113

Deux pointeurs peut être comparé avec l'aide de la fonction de comparaison des objets less, greater etc. Sinon, l'utilisation de couverture en operator< etc, cela n'est possible que si les pointeurs point d'éléments d'un même objet array ou un passé la fin. Sinon, les résultats ne sont pas spécifiés.

20.3.3/8 en C++03

Pour les templates greater, less, greater_equal, et less_equal, les spécialisations pour tout type de pointeur de rendement total de l'ordre, même si le haut-opérateurs <, >, <=, >= ne le font pas.

Pas besoin explicitement de se spécialiser et manuellement la conversion en size_t: diminuer la portabilité de même, depuis la cartographie de l' reinterpret_cast de pointeurs vers des entiers est mise en œuvre défini et n'est pas requis pour un rendement de n'importe quel ordre.


Edit: Pour une réponse plus détaillée, voir ce un.

3voto

Rob Kennedy Points 107381

Non, il n'est pas disponible. La norme dit que les pointeurs ne sont comparables avec le haut-opérateurs quand ils désignent la même matrice ou d'un autre bloc de mémoire. Qui est, le bloc doit avoir été attribué tout à la fois, contrairement aux deux allocations qui pourrait arriver à être adjacents les uns aux autres.

C'est OK:

int x[2];
bool b = &x[0] < &x[1];

Ce n'est pas défini:

int x0;
int x1;
bool b = &x0 < &x1;

C'est OK:

struct foo {
  int x0;
  int x1;
};
foo f;
bool b = &f.x0 < &f.x1;

Les deux valeurs sont membres de la même structure, afin qu'ils appartiennent au même bloc de mémoire (à savoir, fs').

En pratique, cependant, il n'y a rien de mal avec votre définis par comparaison.

Cependant, personnalisé de votre spécialisation est inutile, puisque l' std::less modèle est défini pour les pointeurs, évidemment. Donc, c'est OK:

int x0;
int x1;
std::less<int*> compare;
bool b = compare(&x0, &x1);

Il n'y a encore aucune indication de ce que le résultat doit être, mais vous êtes au moins promis de certains conséquence, par opposition à un comportement indéfini. Vous obtenez un total de la commande, mais vous ne savez pas ce que l' ordre jusqu'à ce que vous l'exécutez.

3voto

Nathan Kitchen Points 2729

Même si vous pouvez penser que la comparaison entre les bits de pointeurs est inoffensif (après tout, ils sont juste des adresses dans la mémoire, non?), il y a de bonnes raisons à la langue standard ne l'encourage pas. Pour l'un, si vous disposez d'un code dont les résultats dépendent de l'ordre relatif des pointeurs (e.g, l'ordre des résultats dépend de l'itération de l'ordre à travers un ensemble ou d'une carte de pointeurs), les résultats seront instables: la Modification de la version du compilateur ou de version de système d'exploitation peuvent modifier les résultats. La reproductibilité est assez précieux pour faire de cette instabilité vaut éviter.

1voto

Dmitry Risenberg Points 1014

N'est-ce pas hash_set vous avez besoin? Cela fera partie de la prochaine norme

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