web-dev-qa-db-fra.com

std :: dynarray vs std :: vector

C++ 14 présente std::dynarray :

std :: dynarray est un conteneur de séquence qui encapsule les tableaux avec une taille qui est fixée à la construction et ne change pas pendant la durée de vie de l'objet.

std::dynarray doit être alloué au moment de l'exécution comme std::vector.

Quels sont donc les avantages et l'utilisation de std::dynarray alors que nous pouvons utiliser std::vector qui est plus dynamique (et aussi redimensionnable)?

81
deepmax

Quels sont donc les avantages et l'utilisation de std::dynarray, quand on peut utiliser std::vector qui est plus dynamique (redimensionnable)?

dynarray est plus petit et plus simple que vector, car il n'a pas besoin de gérer des valeurs de taille et de capacité distinctes, et il n'a pas besoin de stocker d'allocateur.

Cependant, le principal avantage en termes de performances est censé provenir du fait que les implémentations sont encouragées à allouer dynarray sur la pile lorsque cela est possible, en évitant toute allocation de tas. par exemple.

std::dynarray<int> d(5);   // can use stack memory for elements
auto p = new std::dynarray<int>(6);  // must use heap memory for elements

Cette optimisation nécessite la coopération du compilateur, elle ne peut pas être implémentée comme un type de bibliothèque pure, et la magie du compilateur nécessaire n'a pas été implémentée et personne n'est sûr de sa facilité. En raison du manque d'expérience de mise en œuvre, lors de la réunion du comité C++ à Chicago la semaine dernière, il a été décidé de retirer std::dynarray à partir de C++ 14 et pour émettre un document TS (spécification technique) d'extensions de tableau distinct définissant std::experimental::dynarray et des tableaux liés à l'exécution (ARB, similaires aux VLA C99). Cela signifie std::dynarray ne sera presque certainement pas en C++ 14.

81
Jonathan Wakely

Comme vous l'avez dit vous-même, std::dynarray Est pour un tableau dynamique de taille fixe . Il n'est pas redimensionnable. Il s'agit en gros d'une amélioration par rapport à new T[N] Et à std::unique_ptr<T[]>(new T[N]).

Ne pas avoir besoin de redimensionner ou de gérer la capacité signifie que vous pouvez implémenter la structure de données avec moins de complexité et dans moins d'espace.

De plus, std::dynarray Est un animal bizarre qui permet à l'implémentation de l'implémenter de différentes manières, non spécifiques, par ex. il est possible de mettre le tableau sur la pile. L'appel d'une fonction d'allocation est "facultatif". Vous pouvez spécifier un allocateur pour construire les éléments du tableau, mais cela ne fait pas partie du type.

Vous pourriez également vous demander pourquoi nous avons besoin de tableaux de std::dynarray et de longueur variable. Les VLA en C++ 14 sont beaucoup plus restrictifs; elles ne peuvent être que des variables locales et automatiques et n'offrent aucun moyen de spécifier une politique d'allocation, et bien sûr, elles n'ont pas d'interface conteneur standard.


Quelques exemples de 23.3.4.2 d'un "brouillon actuel" (prenez cela, cache Google):

explicit dynarray(size_type c);

Effets: Alloue du stockage pour les éléments c. Peut invoquer ou non le global operator new.

template <class Alloc>
dynarray(size_type c, const Alloc& alloc);

Effets: Équivalent aux constructeurs précédents, sauf que chaque élément est construit avec la construction allocateur d'utilisations.

Que vous puissiez utiliser un allocateur donné pour construire les éléments du tableau est un trait global:

structure du modèle uses_allocator, Alloc>: true_type {};

Nécessite: Alloc doit être un allocateur (17.6.3.5). [ Remarque: La spécialisation de ce trait informe les autres composants de la bibliothèque que dynarray peut être construit avec un allocateur, même s'il n'a pas de allocator_type imbriqué.]

Edit: La réponse de Jonathan Wakely est forcément beaucoup plus autoritaire et perspicace.

31
Kerrek SB