c++11 std::array vs tableau statique vs std::vector
Première question, est-ce une bonne chose pour démarrer à l'aide de c++11 si je vais développer un code pour les 3 années suivantes?
Si c'est cela, quelle est la "meilleure" façon de mettre en œuvre une matrice si je veux l'utiliser avec Lapack? Je veux dire, faire std::vector<std::vector< Type > > Matrix
n'est pas facilement compatible avec Lapack.
Jusqu'à maintenant, j'ai stocké mon matrice avec Type* Matrix(new Type[N])
(le pointeur de la forme avec new
et delete
sont importantes parce que la taille du tableau n'est pas donnée comme un nombre, par exemple 5, mais en tant que variable).
Mais avec le C++11, il est possible d'utiliser std::array. Selon cette site, ce conteneur semble être la meilleure solution... Qu'en pensez-vous?
eh bien, je sais, mais la première question est une question oui/non...
gist.github.com/rmartinho/3959961
La première question aurait été fermé immédiatement pour être "principalement par opinion", et la deuxième question technique, vous auriez eu plus d'attention. Le mélange des deux vous laisse avec un offputting, médiocre question que les gens pourraient simplement sauter par-dessus.
J'ai en fait écrit plus ou moins exactement le même code pour ma matrice en c++03. mais j'ai du mal à faire le tri. c'est pourquoi j'ai considéré l'utilisation de c++11 et peut-être utiliser c++11 std::array au lieu d'un pointeur
OriginalL'auteur PinkFloyd | 2013-09-18
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, si vous allez à apprendre le C++, apprendre le C++11. La précédente norme C++ a été publié en 2003, c'est déjà dix ans. C'est beaucoup dans CE monde. C++11 compétences seront également en douceur traduire à venir C++1y (probablement C++14) standard.
La principale différence entre
std::vector
etstd::array
est la dynamique (en taille et répartition) et de stockage statique. Donc, si vous voulez avoir une matrice de classe qui est toujours, disons, 4x4,std::array<float, 4*4>
fera l'amende juste.Deux de ces classes fournissent
.data()
membre, ce qui devrait produire un pointeur compatible. Notez cependant, questd::vector<std::vector<float>>
NE occuppy contiguë16*sizeof(float)
de mémoire (doncv[0].data()
ne de travail). Si vous avez besoin d'un dynamiquement la taille de la matrice, utilisation uniquevector
et la redimensionner à lawidth*height
taille.Puisque l'accès à des éléments un peu plus difficile (
v[width * y +x]
ouv[height * x + y]
), vous voudrez peut-être fournir une classe wrapper qui vous permettra d'accéder à l'arbitraire du champ par ligne/colonne paire.Puisque vous avez aussi mentionné que C le style des tableaux;
std::array
fournit une interface plus conviviale pour traiter avec le même type de stockage, et devrait donc être préféré; il n'y a rien à gagner avec les tableaux statiques surstd::array
.Comment est-il en désaccord, exactement? Je pense que c'sorts à peu près la même chose.
il me semble qu'ils sont ce qui implique que d'autres récipients (à savoir
std::vector
) ne sont pas aussi efficace d'une C-gamme de style, maisstd::array
est... mais je ne sais pas assez pour comparer l'efficacité de C-gamme de style,std::vector
etstd::array
.std::vector
a (très peu) d'impact sur les performances en raison de sa nature dynamique; parce que la taille de la mémoire requise, n'est pas connu au moment de la compilation, le système d'exploitation de l'allocation de mémoire d'appel doit être faite. C-le style des tableaux etstd::array
sont otoh, que d'une taille fixe et ainsi, ils peuvent être alloués sur la pile sans la nécessité de poser des OS pour plus de mémoire. L'accès à des éléments est aussi rapide dans les deux approches, et se résume à la simple arithmétique des pointeurs. Si vous êtes à la que sérieux au sujet de la performance, vous devriez probablement utiliser des instructions SIMD et de types à utiliser HW-accélération de calculs.Si un
std::array
est allouée de manière statique (c'est à dire dans la section des données; en la déclarant en dehors de toute fonction ou avec lastatic
mot-clé à l'intérieur d'une fonction), puis de ne pas, son adresse est connue au moment de la compilation, permettant à quelques optimisations (c'est à dire pas besoin de déréférencer un pointeur)? Il devrait donc être plus rapide?OriginalL'auteur Bartek Banachewicz
C'est un très fin de répondre à la question, mais si quelqu'un lit ceci, je veux juste souligner que l'on doit presque jamais de mettre en œuvre une matrice comme un "vecteur de vecteurs". La raison en est que chaque ligne de la matrice est stockée dans certains endroit aléatoire sur le tas. Cela signifie que les opérations matricielles va faire beaucoup d'aléatoire l'accès à la mémoire conduisant à des défauts de cache, ce qui ralentit la mise en œuvre considérablement.
En d'autres termes, si vous vous souciez au sujet de la performance, de même allouer un
array/std::array/std::vector
de taillerows * columns
, puis utiliser des fonctions wrapper qui transforme une paire de nombres entiers à l'élément correspondant dans le tableau. Sauf si vous avez besoin de l'appui des choses comme le retour par référence aux lignes de la matrice, puis toutes ces options devrait fonctionner parfaitement.Cela dépend entièrement du degré de contention pour le tas. Si vous venez alloué un vecteur de vecteurs sans détour, sans rien d'autre de la tentative de répartition (ou de la libération), les tampons risque bien de se retrouver un après l'autre.
std::vector<std::array<T, RowSize>>
est plus pratique et rapide, comme plat de lignes*colonnes avec wrapperOriginalL'auteur Edvard Fagerholm