'size_t' vs 'container :: size_type'

108

Y a-t-il une différence entre size_tet container::size_type?

Ce que je comprends est size_tplus générique et peut être utilisé pour tout size_typeart.

Mais est-il container::size_typeoptimisé pour certains types de conteneurs?

Charles Khunt
la source

Réponses:

108

Les conteneurs standard se définissent size_typecomme un typedef to Allocator::size_type(Allocator est un paramètre de modèle), qui std::allocator<T>::size_typeest généralement défini comme étant size_t(ou un type compatible). Donc pour le cas standard, ce sont les mêmes.

Cependant, si vous utilisez un allocateur personnalisé, un type sous-jacent différent peut être utilisé. C'est donc container::size_typepréférable pour une généralité maximale.

Evan Teran
la source
2
Pouvez-vous clarifier cette réponse? J'ai regardé les projets de normes aussi loin que possible N1804et je ne vois aucune relation entre Allocator::size_typeet size_type. Un rapide coup d'œil à libstdc ++ ne montre rien de semblable non plus.
Shafik Yaghmour
1
@ShafikYaghmour, Donc cette réponse est légèrement obsolète, mais pour maximiser la portabilité je pense que le conseil est toujours valable: C ++ 03 a spécifié "Table 32: size_type: un type qui peut représenter la taille du plus gros objet dans le modèle d'allocation." A l'époque, size_tle pari était la mise en œuvre pratique de ces contraintes. Cependant, dans C ++ 11, il est maintenant défini essentiellement comme: std::make_unsigned<X::difference_type>::typepar défaut. Ce qui, en pratique, sera probablement le même ou compatible avec size_t.
Evan Teran
2
ATTENTION, la réponse est incorrecte .... voir stackoverflow.com/questions/4849678/... TL: DR: les allocateurs size_type doivent être size_t et en C ++ 17 size_type sera obsolète tel quel.
user3063349
1
@ user3063349 Je ne vois rien dans cette page, ni dans la norme C ++ 2017 (23.10.8), pour faire allusion à la size_typedépréciation. Ce qui donne?
Marc 2377
42
  • size_test défini comme le type utilisé pour la taille d'un objet et dépend de la plate - forme .
  • container::size_typeest le type utilisé pour le nombre d'éléments dans le conteneur et dépend du conteneur .

Tous les stdconteneurs utilisent size_tcomme le size_type, mais chaque fournisseur de bibliothèque indépendant choisit un type qu'il trouve approprié pour son conteneur.

Si vous regardez , vous constaterez que le size_typedes conteneurs Qt dépend de la version. Dans Qt3 c'était le cas unsigned intet dans Qt4, il a été changé en int.

TimW
la source
1
Je trouve un peu étrange d'avoir la taille de quelque chose exprimée en int. Pourrait-on jamais avoir une taille négative pour un conteneur?
Mihai Todor
10
@MihaiTodor: il n'est pas rare que les gens utilisent des types signés pour tout, je suppose que Qt fait de même. La raison en est que les opérations mixtes (en particulier les comparaisons) sont une telle zone sinistrée que de nombreuses personnes préfèrent éviter d'utiliser des types non signés pour les nombres, plutôt que de devoir gérer et / ou éviter des opérations mixtes. Ce n'est pas parce que les types non signés ne peuvent pas exprimer des nombres négatifs que vous devez les utiliser pour des nombres qui ne peuvent pas être négatifs :-) J'avoue que je suis surpris que ce soit intplutôt que ssize_t, intc'est un peu petit.
Steve Jessop
2
"Tous les conteneurs std utilisent size_t comme size_type" très très faux et trompeur. Oui, ils le font habituellement (au moins tous mes compilateurs l'ont fait de cette façon) mais la référence du langage C ++ ne dit pas, qu'il doit être similaire pour tous les conteneurs stl !! so care
user3063349
8

Car std::[w]string, std::[w]string::size_typeest égal à std::allocator<T>::size_type, qui est égal à std::size_t. Pour les autres conteneurs, il s'agit d'un type entier non signé défini par l'implémentation.

Parfois, il est utile d'avoir le type exact, donc par exemple, on sait où le type s'enroule (comme, vers UINT_MAX) afin de pouvoir l'utiliser. Ou pour les modèles, où vous devez vraiment passer deux types identiques aux modèles de fonction / classe.

Souvent, je trouve que j'utilise size_tpour la brièveté ou les itérateurs de toute façon. Dans le code générique, puisque vous ne savez généralement pas avec quelle instance de conteneur votre modèle est utilisé et quelle taille ont ces conteneurs, vous devrez utiliser le Container::size_typetypedef si vous devez stocker la taille des conteneurs.

Johannes Schaub - litb
la source