De schoonste manier om een array met constante grootte te kopiëren in c++11

Ik merk vaak dat ik de inhoud van arrays met een constante grootte wil kopiëren, meestal schrijf ik iets in de trant van:

float a[4] = {0,1,2,3};
float b[4];
for(int i=0; i<4; i++){
    b[i]=a[i];
}

De laatste tijd schrijf ik een bibliotheek voor lineaire calculus voor educatieve doeleinden, en ik vroeg me af of er een betere manier was om dit te doen.

Het eerste dat in me opkwam, was het gebruik van memcpy:

memcpy(b, a, sizeof(float) * 4);

Maar dit lijkt me erg c-achtig en foutgevoelig. Ik vind het leuk om mijn fouten te hebben tijdens het compileren, en dit kan lelijk worden voor gegevenstypen met niet-triviale kopieerconstructors, of als ik vergeet te vermenigvuldigen met sizeof(datatype).

Omdat ik een wiskundebibliotheek schrijf die ik intensief ga gebruiken, zijn prestaties erg belangrijk voor mij. Zijn de compilers van vandaag slim genoeg om te begrijpen dat het eerste voorbeeld slechts een stuk geheugen kopieert en dit optimaliseert om net zo efficiënt te zijn als de tweede oplossing?

Misschien is er een functie in de standaardbibliotheek die me kan helpen? Iets nieuws in c++11? Of moet ik gewoon een macro of een sjabloonfunctie maken?


Antwoord 1, autoriteit 100%

Als je std::arraygebruikt in plaats van een ingebouwde array (wat je zou moeten doen), wordt het heel eenvoudig. Het kopiëren van een array is dan hetzelfde als het kopiëren van een ander object.

std::array<float,4> a = {0,1,2,3};
std::array<float,4> b = a;

Antwoord 2, autoriteit 67%

De C++03-manier

Gebruik std::copy():

float a[4] = {0,1,2,3};
float b[4];
std::copy(a,a + 4, b);

Dat is zo goed als mogelijk.

De C++11-manier

std::copy(std::begin(a), std::end(a), std::begin(b));

Als je std::array kunt gebruiken

Met std::arraydoe je gewoon een simpele opdracht:

std::array<float,4> a = {0,1,2,3};
auto b = a;

Antwoord 3, autoriteit 26%

Voor geïnteresseerden in C++03 (en ook C) oplossing – gebruik altijd struct die een array bevat in plaats van alleen array:

struct s { float arr[5]; };

Structs kunnen standaard worden gekopieerd.

Het equivalent in C++11 is, al genoemd, std::array<float,5>;


Antwoord 4, autoriteit 5%

De onderstaande methode werkt ook voor gewone arrays std:array.

float a[4] = {0,1,2,3};
float b[4];
std::copy(std::begin(a), std::end(a), b);

Antwoord 5, autoriteit 3%

#include <algorithm>
std::copy_n(a, 4, b)

Other episodes