std::array
est largement supérieur aux tableaux C. Et même si je veux interagir avec le code hérité, je peux simplement utiliser std::array::data()
. Y a-t-il une raison pour laquelle je voudrais un jour un tableau à l'ancienne?
la source
std::array
est largement supérieur aux tableaux C. Et même si je veux interagir avec le code hérité, je peux simplement utiliser std::array::data()
. Y a-t-il une raison pour laquelle je voudrais un jour un tableau à l'ancienne?
À moins d'avoir manqué quelque chose (je n'ai pas suivi de trop près les changements les plus récents de la norme), la plupart des utilisations des tableaux de style C subsistent. std::array
autorise l'initialisation statique, mais ne compte toujours pas les initialiseurs à votre place. Et comme la seule véritable utilisation des tableaux de style C auparavant std::array
était pour les tables initialisées statiquement comme:
MyStruct const table[] =
{
{ something1, otherthing1 },
// ...
};
en utilisant les fonctions habituelles begin
et de end
modèle (adoptées en C ++ 11) pour les parcourir. Sans jamais parler de la taille, que le compilateur détermine à partir du nombre d'initialiseurs.
EDIT: Une autre chose que j'ai oubliée: les chaînes littérales sont toujours des tableaux de style C; c'est à dire avec le type char[]
. Je ne pense pas que quiconque exclurait l'utilisation de chaînes littérales simplement parce que nous l'avons fait std::array
.
const char[]
Non, euh, dis-le franchement. Et en 30 caractères.
Bien sûr, vous avez besoin de tableaux C pour implémenter
std::array
, mais ce n'est pas vraiment une raison pour laquelle un utilisateur voudrait un tableau C. De plus, non,std::array
n'est pas moins performant qu'un tableau C et dispose d'une option pour un accès vérifié par les limites. Et enfin, il est tout à fait raisonnable pour tout programme C ++ de dépendre de la bibliothèque Standard - c'est en quelque sorte le point d'être Standard - et si vous n'avez pas accès à une bibliothèque Standard, alors votre compilateur est non conforme et le La question est étiquetée "C ++", pas "C ++ et les choses non-C ++ qui manquent la moitié de la spécification parce qu'elles la jugent inappropriée.".la source
std::array
dans une implémentation autonome C ++ 11.On dirait que l'utilisation de tableaux multidimensionnels est plus facile avec les tableaux C que
std::array
. Par exemple,par opposition à
Également en raison de la propriété de décroissance automatique des tableaux C,
c_arr[i]
dans l'exemple ci-dessus, la décomposition en un pointeur se fera et il vous suffit de passer les dimensions restantes comme deux paramètres supplémentaires. Mon point est que lac_arr
copie n'est pas coûteuse. Cependant, lacpp_arr[i]
copie sera très coûteuse.la source
array
à une fonction sans perdre de dimensions. Et si vous le transmettez à un modèle de fonction, cette fonction peut déduire à la fois la dimension et la taille de chaque dimension, ou juste l'une des deux. Cela peut être intéressant pour les bibliothèques de modèles scientifiques qui travaillent principalement sur des dimensions arbitraires.template <typename T, int M, int N> using array2d = std::array<std::array<T, N>, M>;
devrait résoudre l'un de ces problèmes.c_arr
est très coûteux à copier! Vous devez fournir le code pour le faire vous-même. Le pointeur vers lequel il se désintègre est un équivalent plus proche d'une référence qu'une copie et vous pouvez l'utiliserstd::array
pour passer une référence si c'est ce que vous voulez.std::size_t
placeint
? désolé pour pinailler, mais cela le rendrait universel.size_t
si vous le souhaitez, même si je ne peux pas imaginer qu'il existe de nombreux scénarios où des tableaux de plus de 4 milliards de lignes ou de colonnes sont nécessaires.Comme Sumant l'a dit, les tableaux multidimensionnels sont beaucoup plus faciles à utiliser avec les tableaux C intégrés qu'avec
std::array
.Lorsqu'elles sont imbriquées, elles
std::array
peuvent devenir très difficiles à lire et inutilement verbeuses.Par exemple:
par rapport à
Notez également que
begin()
,end()
etsize()
tous renvoient des valeurs sans signification lorsque vous imbriquezstd::array
.Pour ces raisons, j'ai créé mes propres conteneurs de tableaux multidimensionnels de taille fixe,
array_2d
etarray_3d
. Ils sont analogues àstd::array
mais pour des tableaux multidimensionnels de 2 et 3 dimensions. Ils sont plus sûrs et n'ont pas de pires performances que les tableaux multidimensionnels intégrés. Je n'ai pas inclus de conteneur pour les tableaux multidimensionnels avec des dimensions supérieures à 3 car ils sont rares. En C ++ 0x, une version de modèle variadique peut être créée qui prend en charge un nombre arbitraire de dimensions.Un exemple de la variante bidimensionnelle:
La documentation complète est disponible ici:
http://fsma.googlecode.com/files/fsma.html
Vous pouvez télécharger la bibliothèque ici:
http://fsma.googlecode.com/files/fsma.zip
la source
arr[x][y]
, vous ne pouvez pas dire s'ilarr
s'agit d'un tableau de tableaux, d'un tableau de pointeurs, d'un pointeur vers un tableau ou d'un pointeur vers un pointeur; tout pour les implémentations sont légitimes, en fonction de vos besoins. Et probablement la plupart des cas d'utilisation réels pour les tableaux multidimensionnels nécessitent que la taille soit déterminée au moment de l'exécution.Les tableaux de style C qui sont disponibles en C ++ sont en fait beaucoup moins polyvalents que les véritables tableaux C. La différence est qu'en C, les types de tableaux peuvent avoir des tailles d' exécution . Ce qui suit est du code C valide, mais il ne peut être exprimé ni avec des tableaux de style C C ++ ni avec les
array<>
types C ++ :En C ++, vous devrez allouer le tableau temporaire sur le tas:
Cela ne peut pas être réalisé avec
std::array<>
, car cebar
n'est pas connu au moment de la compilation, cela nécessite l'utilisation de tableaux de style C en C ++ ou destd::vector<>
.Alors que le premier exemple pourrait être relativement facilement exprimé en C ++ (bien que nécessitant
new[]
etdelete[]
), ce qui suit ne peut pas être réalisé en C ++ sansstd::vector<>
:Le fait est que les pointeurs vers les tableaux de lignes
int (*)[width]
ne peuvent pas utiliser une largeur d'exécution en C ++, ce qui rend tout code de manipulation d'image beaucoup plus compliqué en C ++ qu'en C.Une implémentation C ++ typique de l'exemple de manipulation d'image ressemblerait à ceci:Ce code fait exactement les mêmes calculs que le code C ci-dessus, mais il doit effectuer le calcul d'index à la main partout où les indices sont utilisés . Pour le cas 2D, cela est toujours faisable (même si cela offre de nombreuses possibilités de se tromper dans le calcul de l'indice). Cela devient vraiment méchant dans le cas de la 3D, cependant.
J'aime écrire du code en C ++. Mais chaque fois que j'ai besoin de manipuler des données multidimensionnelles, je me demande vraiment si je dois déplacer cette partie du code vers C.
la source
gcc
par exemple). C11 a rendu facultatifs un certain nombre de choses intéressantes, et je ne pense pas que ce soit parce qu'ils veulent interdire cette fonctionnalité. J'ai tendance à voir cela comme un signe qu'ils voulaient abaisser le niveau d'écriture d'un compilateur entièrement conforme aux normes: les VLA sont assez difficiles à implémenter, et beaucoup de code peut s'en passer, il est donc logique pour un nouveau compilateur sur un nouveau plate-forme pour ne pas avoir à mettre en œuvre les VLA tout de suite.Peut-être que le
std::array
n'est pas lent. Mais j'ai fait des analyses comparatives en utilisant simple store et en lisant depuis le std :: array; Voir les résultats de référence ci-dessous (sur W8.1, VS2013 Update 4):Selon les marques négatives, le code que j'ai utilisé est dans le pastebin ( lien )
Le code de classe de référence est ici ;
Je ne sais pas grand-chose sur les benchmarks ... Mon code est peut-être défectueux
la source
long test_arr_without_init() { return ARR_SIZE; }
void test_arr_without_init() {}
maintenant. Vous devez vraiment sauter à travers des cercles pour vous assurer que le code que vous mesurez est le code que vous souhaitez mesurer.std::array
la source
std::array
sera moins performant qu'un tableau C.at()
dedans, ce n'est pas dedansoperator[]
, juste commestd::vector
. Il n'y a pas de diminution des performances ou de gonflement du codestd::array
, le compilateur est conçu pour optimiser ce genre de chose. Et, bien sûr, l'ajout de la fonction vérifiée est un excellent outil de débogage et un grand avantage. @Lou Franco: Tout le code C ++ peut dépendre de la bibliothèque Standard - c'est un peu ce à quoi il sert. @Earlz: Si vous n'avez pas STL disponible, alors ce n'est pas C ++, et c'est la fin de cela.std::array
soit plus grande que l'utilisation du tableau C équivalent.