Wenn ich ein sehr einfaches Array wie erstellen möchte
int myArray[3] = {1,2,3};
Soll ich std::array
stattdessen verwenden?
std::array<int, 3> a = {{1, 2, 3}};
Was sind die Vorteile der Verwendung von std :: array gegenüber den üblichen? Ist es performanter? Einfacher zu handhaben für das Kopieren / Zugreifen?
for (auto i = ++std::begin(myArray); . . .
kann nicht einmal kompiliert werden (es scheint, dass Temporäre des fundamentalen Typs nicht veränderbar sind, zumindest nicht mit Clang 6)struct Direction { int32_t dw; int32_t dh; };
undstatic const Direction DIRECTIONS[DIRECTIONS_COUNT] { { -1, 1}, {0,1}, {1,1} , { 1, 0 }, {1,-1}, {0,-1} , {-1,-1}, {-1,0} };
kompiliert. Wenn Sie jedoch zu einerstd::array<Direction,DIRECTIONS_COUNT>
Liste mit derselben Initialisierer wechseln , wird plötzlich der Fehler "Zu viele Initialisierer" angezeigt. (VS 2019 Community mit Sprache = C ++ 17)std::array
Initialisierung?Antworten:
Es hat eine benutzerfreundliche Wertesemantik, so dass es nach Wert an Funktionen übergeben oder von diesen zurückgegeben werden kann. Die Benutzeroberfläche erleichtert das Ermitteln der Größe und die Verwendung mit iteratorbasierten Algorithmen im STL-Stil.
Es sollte genau das gleiche sein. Per Definition ist es ein einfaches Aggregat, das ein Array als einziges Mitglied enthält.
Ja.
quelle
A
std::array
ist ein sehr dünner Wrapper um ein Array im C-Stil, im Grunde definiert alstemplate<typename T, size_t N> class array { public: T _data[N]; T& operator[](size_t); const T& operator[](size_t) const; // other member functions and typedefs };
Es ist ein Aggregat und ermöglicht es Ihnen, es fast wie einen grundlegenden Typ zu verwenden (dh Sie können Werte übergeben, zuweisen usw., während ein Standard-C-Array nicht direkt einem anderen Array zugewiesen oder kopiert werden kann). Sie sollten sich eine Standardimplementierung ansehen (von Ihrer bevorzugten IDE zur Definition springen oder direkt öffnen
<array>
). Sie ist ein Teil der C ++ - Standardbibliothek, der recht einfach zu lesen und zu verstehen ist.quelle
std::array
ist als Zero-Overhead-Wrapper für C-Arrays konzipiert, der den "normalen" Wert wie die Semantik der anderen C ++ - Container angibt.Sie sollten keinen Unterschied in der Laufzeitleistung bemerken, während Sie die zusätzlichen Funktionen nutzen können.
Die Verwendung
std::array
vonint[]
Arrays anstelle von Stilen ist eine gute Idee, wenn Sie C ++ 11 oder Boost zur Hand haben.quelle
Die Situation scheint komplizierter zu sein, da
std::array
je nach Plattform nicht immer identischer Assembler-Code im Vergleich zu C-Array erzeugt wird.Ich habe diese spezielle Situation auf Godbolt getestet :
#include <array> void test(double* const C, const double* const A, const double* const B, const size_t size) { for (size_t i = 0; i < size; i++) { //double arr[2] = {0.e0};// std::array<double, 2> arr = {0.e0};//different to double arr[2] for some compiler for (size_t j = 0; j < size; j++) { arr[0] += A[i] * B[j]; arr[1] += A[j] * B[i]; } C[i] += arr[0]; C[i] += arr[1]; } }
GCC und Clang erzeugen identischen Assemblycode sowohl für die C-Array-Version als auch für die
std::array
Version.MSVC und ICPC erzeugen jedoch für jede Array-Version unterschiedliche Assembler-Codes. (Ich habe ICPC19 mit
-Ofast
und getestet-Os
; MSVC-Ox
und-Os
)Ich habe keine Ahnung, warum dies der Fall ist (ich würde in der Tat ein genau identisches Verhalten von std :: array und c-array erwarten). Möglicherweise werden verschiedene Optimierungsstrategien angewendet.
Als kleines Extra: Es scheint einen Fehler in ICPC mit zu geben
#pragma simd
zur Vektorisierung bei Verwendung des C-Arrays in bestimmten Situationen (der C-Array-Code erzeugt eine falsche Ausgabe; die
std::array
Version funktioniert einwandfrei).Leider habe ich noch kein minimales Arbeitsbeispiel dafür, da ich dieses Problem bei der Optimierung eines ziemlich komplizierten Codeteils entdeckt habe.
Ich werde einen Fehlerbericht an Intel senden, wenn ich sicher bin, dass ich nicht nur etwas über C-Array /
std::array
und falsch verstanden habe#pragma simd
.quelle
std::array
hat Wertesemantik, während Raw-Arrays dies nicht tun. Dies bedeutet, dass Sie es kopierenstd::array
und wie einen primitiven Wert behandeln können. Sie können sie als Wert oder Referenz als Funktionsargumente empfangen und als Wert zurückgeben.Wenn Sie niemals ein kopieren
std::array
, gibt es keinen Leistungsunterschied als bei einem Raw-Array. Wenn Sie Kopien erstellenstd::array
müssen, tun Sie das Richtige und sollten dennoch die gleiche Leistung erbringen.quelle