La taille de std::array est-elle définie par standard

En C++11 std::array est défini pour avoir un stockage et des performances contigus qui ne sont pas pires qu'un tableau, mais je ne peux pas décider si les différentes exigences de la norme impliquent que std::array a la même taille et la même disposition de mémoire qu'un Tableau normal. C'est-à-dire Pouvez-vous compter sur sizeof(std::array<int,N>) == sizeof(int)*N ou est-ce spécifique à l'implémentation?

En particulier, est-ce garanti pour fonctionner comme vous le souhaitez:

std::vector< std::array<int, N> > x(M);
typedef (*ArrayPointer)[N];
ArrayPointer y = (ArrayPointer) &x[0][0];
// use y like normal multidimensional array

Cela fonctionne dans les deux compilateurs que j'ai essayés (GNU & Intel). En outre, tous les 3ème la documentation de partie que j'ai pu trouver (comme ceci ), indique que std:: array est tout aussi efficace en mémoire qu'un tableau simple, ce qui, combiné à l'exigence contiguë, impliquerait qu'il doit avoir une disposition de mémoire identique. Cependant, je ne trouve pas cette exigence dans la norme.

32
demandé sur Ben Voigt 2013-10-01 00:29:17

1 réponses

C'est presque requis. Plus précisément, le §23.3.2.1 / 2 dit:

Un tableau est un agrégat (8.5.1) qui peut être initialisé avec la syntaxe

array<T, N> a = { initializer-list };

Où {[1] } est une liste séparée par des virgules de Jusqu'À N éléments dont les types sont convertibles en T.

Comme il s'agit d'un agrégat, il ne peut utiliser aucun constructeur pour convertir les données de la liste d'initialisation au format correct. Cela ne laisse vraiment qu'une possibilité: à propos de la seule chose il peut stocker les valeurs elles-mêmes.

Je suppose que serait possible pour un std::array de stocker une sorte de données auxiliaires après les données spécifiées, telles que la mémoire supplémentaire définie sur une valeur prédéfinie, donc si vous écrivez après la fin du tableau, vous changeriez probablement ces données. Le compilateur / exécution vérifierait alors ces valeurs à l'arrêt, et si vous aviez changé les valeurs, signalez le comportement indéfini de votre code.

Il est également possible qu'un compilateur puisse faites le remplissage / alignement différemment pour un std::array que pour un tableau intégré. Un exemple évident pour lequel cela pourrait même être souhaitable serait de prendre en charge les exigences de super-alignement, telles que les données à utiliser avec les instructions SSE D'Intel. Un tableau intégré ne peut pas supporter le super-alignement, mais je pense que la spécification de std::array pourrait être à peine assez lâche pour le permettre.

Bottom line: sans entrer dans les questions de combien de possibilités pourraient exister, c'est assez clair que std::array ne doit pas nécessairement suivre la règle que vous demandez.

25
répondu Jerry Coffin 2013-09-30 21:17:11