C-Array dem std::array von C++ zuweisen? (std::array = T[U]) – es existiert kein passender Konstruktor von “T [U]” nach “std::array”

Lesezeit: 4 Minuten

Ich versuche, einem C++ std::array ein C-Array zuzuweisen.

Wie mache ich das am saubersten und ohne unnötige Kopien etc.?

Beim machen

int X[8];
std::array<int,8> Y = X;

Ich erhalte einen Compiler-Fehler: “Es existiert kein geeigneter Konstruktor”.

  • Beachten Sie, dass std::array hat keine benutzerdefinierten Konstruktoren, da es als wichtig erachtet wurde, seinen Status als Aggregattyp beizubehalten.

    – Benjamin Lindley

    6. Oktober 2014 um 15:44 Uhr

Benutzeravatar von juanchopanza
Juanchopanza

Es gibt keine Konvertierung von einfachem Array zu std::arrayaber Sie können die Elemente von einem zum anderen kopieren:

std::copy(std::begin(X), std::end(X), std::begin(Y));

Hier ist ein funktionierendes Beispiel:

#include <iostream>
#include <array>
#include <algorithm>  // std::copy

int main() {
    int X[8] = {0,1,2,3,4,5,6,7};
    std::array<int,8> Y;
    std::copy(std::begin(X), std::end(X), std::begin(Y));
    for (int i: Y)
        std::cout << i << " ";
    std::cout << '\n';
    return 0;
}

  • <array> garantiert Ihnen std::begin und std::end schon; kein Bedarf für <iterator>.

    – TC

    6. Oktober 2014 um 15:44 Uhr

  • @TC Das kann ich nicht finden, zumindest nicht im C ++ 11-Standard. Haben Sie eine Referenz?

    – Juanchopanza

    6. Oktober 2014 um 16:43 Uhr

  • @juanchopanza 24.6.5/1: „Zusätzlich zur Verfügbarkeit über die Einbeziehung der <iterator> Header, die Funktionsvorlagen in 24.6.5 [overloads of std::begin and std::end] sind verfügbar, wenn einer der folgenden Header enthalten ist: <array>, <deque>, <forward_list>, <list>, <map>, <regex>, <set>, <string>, <unordered_map>, <unordered_set>und <vector>.”

    – Casey

    6. Oktober 2014 um 17:39 Uhr


  • @dummlerner std::copy ist so unsicher wie std::copy_n. Warum denken Sie std::copy_n ist sicher?

    – Rakete1111

    28. April 2017 um 17:18 Uhr

  • @Rakete1111 Das habe ich nicht gesagt copy_n ist sicher. Ich dachte mit copy_n zwingt den Programmierer, über die richtige Größe zum Kopieren nachzudenken, wodurch die Möglichkeit versteckter Überlauffehler verringert wird. Aber das scheint nicht richtig zu sein, da es darauf ankommt. Danke für den Hinweis.

    – Dummkopf

    30. April 2017 um 2:31 Uhr

C++20 hat std::to_array Funktion

Der Code ist also

int X[8];
std::array<int, 8> Y = std::to_array(X);

https://godbolt.org/z/Efsrvzs7Y

Benutzeravatar von Radoslaw Garbacz
Radosław Garbacz

Ich weiß, es ist eine Weile her, aber vielleicht immer noch nützlich (für jemanden). Die oben bereitgestellten Lösungen sind großartig, aber vielleicht wären Sie an einer weniger eleganten, aber möglicherweise schnelleren Lösung interessiert:

    #include <array>
    #include <string.h>
    
    using namespace std;
 
    double A[4] = {1,2,3,4};
    array<double, 4> B;
    memcpy(B.data(), A, 4*sizeof(double));

Die Array-Größe kann bei Bedarf auf andere (dynamischere) Weise bestimmt werden, hier ist nur eine Idee. Ich habe die Leistung beider Lösungen nicht getestet.

Der hier vorgeschlagene erfordert um die richtige Größe bereitzustellen, da sonst schlimme Dinge passieren können.

Bearbeiten:
Die folgenden Kommentare haben mich veranlasst, die Tests durchzuführen, und es sei denn, jemand versucht wirklich, das Maximum an Leistung herauszuholen, lohnt es sich nicht (Test wird pro Schleife hin und her kopiert):
B-Größe: 100000 getestete Kopie vs. memcpy auf 100000-Element-Arrays mit 100000 Schleifenanzahl:
** kopieren() = 9,4986 Sek
** memcpy() = 9,45058 Sek
B-Größe: 100000 getestete Kopie vs. memcpy auf 100000-Element-Arrays mit 100000 Schleifenanzahl:
** kopieren() = 8,88585 Sek
** memcpy() = 9,01923 Sek
B-Größe: 100000 getestete Kopie vs. memcpy auf 100000-Element-Arrays mit 100000 Schleifenanzahl:
** kopieren() = 8,64099 Sek
** memcpy() = 8,62316 Sek
B-Größe: 100000 getestete Kopie vs. memcpy auf 100000-Element-Arrays mit 100000 Schleifenanzahl:
** kopieren() = 8,97016 Sek
** memcpy() = 8,76941 Sek

  • Es ist einfacher und robuster zu verwenden sizeof(A) für das Größenargument in memcpy

    – SomeWittyBenutzername

    13. November 2020 um 6:09 Uhr

  • Ganz schön die fette Aussage „Schneller“ und einen Satz später „Nicht auf Leistung geprüft“. AFAIK: stackoverflow.com/a/4707028/2548287 => std::copy ist für den Compiler dasselbe wie memcpy (dh std::copy ruft memcpy auf oder wird einfach vektorisiert).

    – Gizmo

    13. November 2020 um 7:39 Uhr

  • Alle gültigen Kommentare. Wie ich geschrieben habe, ist es “möglicherweise” schneller, da ich es nicht getestet habe. Aber Ihr Kommentar hat mich dazu gebracht, den Test zu machen, und der Unterschied ist die Hässlichkeit der Verwendung von “memcpy” nicht wert – sie sind fast gleich, wobei “memcpy” nur etwas schneller ist.

    – Radosław Garbacz

    14. November 2020 um 16:40 Uhr


  • @SomeWittyBenutzername OMG! Bitte berechnen Sie niemals das Größenargument von memcpy von der Quelle. Ich bitte Sie, immer die Größe des Zielobjekts zu verwenden (B.size() in diesem Fall)

    – Ve

    9. Dezember 2021 um 9:03 Uhr

  • @Ves Wenn Sie sich Sorgen über einen möglichen Zielpufferüberlauf machen, gibt es andere Möglichkeiten, damit umzugehen, und sie sind für diese Frage nicht relevant. Ihr Vorschlag schaltet nur den möglichen Zielpufferüberlauf mit dem Quellpufferüberlauf um.

    – SomeWittyBenutzername

    9. Dezember 2021 um 22:24 Uhr

1389150cookie-checkC-Array dem std::array von C++ zuweisen? (std::array = T[U]) – es existiert kein passender Konstruktor von “T [U]” nach “std::array”

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy