Was ist der einfachste Weg, um ein Array in einen Vektor umzuwandeln?


92

Was ist der einfachste Weg, um ein Array in einen Vektor umzuwandeln?

void test(vector<int> _array)
{
  ...
}

int x[3]={1, 2, 3};
test(x); // Syntax error.

Ich möchte x auf einfachste Weise vom int-Array in den Vektor konvertieren.

Antworten:


138

Verwenden Sie den vectorKonstruktor, der zwei Iteratoren akzeptiert, beachten Sie, dass Zeiger gültige Iteratoren sind, und verwenden Sie die implizite Konvertierung von Arrays in Zeiger:

int x[3] = {1, 2, 3};
std::vector<int> v(x, x + sizeof x / sizeof x[0]);
test(v);

oder

test(std::vector<int>(x, x + sizeof x / sizeof x[0]));

wo sizeof x / sizeof x[0]ist offensichtlich 3in diesem Zusammenhang; Dies ist die generische Methode, um die Anzahl der Elemente in einem Array zu ermitteln. Beachten Sie, dass x + sizeof x / sizeof x[0]ein Element über das letzte Element hinaus zeigt.


1
Kannst du es bitte erklären? Ich habe diesen vector<int> a(5,10);Mittelwert make room for 5 int bereits gelesen und mit 10 initialisiert. Aber wie funktioniert dein x, x + ...? können Sie erklären?
Asif Mushtaq

1
@UnKnown anstatt auszuwählen vector<int>::vector(size_type, int), wird ausgewählt vector<int>::vector(int*, int*), wodurch der durch dieses Zeigerpaar angegebene Bereich kopiert wird. Die erste ist Überlastung (2), die zweite ist Überlastung (4) hier
Caleth

1
Unter c ++ 11 ist std :: Extent besser als die Größe der Methode. sizeof x / sizeof x[0] == std::extent<decltype(x)>::value
Isaac Pascual

112

Persönlich gefällt mir der C ++ 2011-Ansatz sehr gut, da Sie weder sizeof()die Array-Grenzen verwenden noch daran denken müssen, sie anzupassen, wenn Sie jemals die Array-Grenzen ändern (und wenn Sie möchten, können Sie auch die entsprechende Funktion in C ++ 2003 definieren ):

#include <iterator>
#include <vector>
int x[] = { 1, 2, 3, 4, 5 };
std::vector<int> v(std::begin(x), std::end(x));

Natürlich möchten Sie mit C ++ 2011 möglicherweise trotzdem Initialisierungslisten verwenden:

std::vector<int> v({ 1, 2, 3, 4, 5 });

2
Kopiert es das Array oder zeigt es nur darauf? Ich bin besorgt um Leistung
kirill_igum

2
std::vector<T>besitzt immer die TObjekte. Dies hat zwei Auswirkungen: Wenn Objekte in einen Vektor eingefügt werden, werden sie kopiert und im Speicher zusammengefasst. Bei relativ kleinen Objekten, z. B. Sequenzen kurzer Zeichenfolgen, ist die Kollokation ein großer Leistungsgewinn. Wenn Ihre Objekte groß und teuer zu kopieren sind, möchten Sie möglicherweise [irgendwie ressourcenverwaltete] Zeiger auf die Objekte speichern. Welcher Ansatz effizienter ist, hängt von den Objekten ab, aber Sie haben die Wahl.
Dietmar Kühl

Wenn ich also eine C ++ - und eine AC-Bibliothek verbinden und von einem C-Array auf einen Vektor und zurück kopieren möchte, gibt es keine Möglichkeit, die Strafe für 2 Kopien zu bezahlen? (Ich benutze Eigenbibliothek und gsl)
kirill_igum

16

Zeiger können wie alle anderen Iteratoren verwendet werden:

int x[3] = {1, 2, 3};
std::vector<int> v(x, x + 3);
test(v)

2
Im wirklichen Leben möchten Sie möglicherweise die Arraygröße abstrahieren, indem Sie beispielsweise die const size_t X_SIZE = 3;Arraygröße angeben oder aus sizeof berechnen. Ich habe diesen Teil aus Gründen der Lesbarkeit weggelassen.
Rafał Rawicki

11

Sie stellen hier die falsche Frage - anstatt alles in einen Vektor zu zwingen, fragen Sie, wie Sie den Test konvertieren können, um mit Iteratoren anstelle eines bestimmten Containers zu arbeiten. Sie können auch eine Überladung bereitstellen, um die Kompatibilität zu gewährleisten (und gleichzeitig andere Container kostenlos zu handhaben):

void test(const std::vector<int>& in) {
  // Iterate over vector and do whatever
}

wird:

template <typename Iterator>
void test(Iterator begin, const Iterator end) {
    // Iterate over range and do whatever
}

template <typename Container>
void test(const Container& in) {
    test(std::begin(in), std::end(in));
}

Was Sie tun können:

int x[3]={1, 2, 3};
test(x); // Now correct

( Ideone-Demo )


"Anstatt alles in einen Vektor zu zwingen, fragen Sie, wie Sie den Test so konvertieren können, dass er mit Iteratoren anstelle eines bestimmten Containers funktioniert." Warum ist das besser?
Aquirdturtle

1
@aquirdturtle, weil Sie jetzt, anstatt nur Vektoren zu unterstützen, Listen und Arrays unterstützen und Container aufladen und Iteratoren und Bereiche transformieren und ...
Flexo

2
und Sie mussten die Daten nicht kopieren
Lightness Races in Orbit

2

Ein einfacher Weg kann die Verwendung einer assign()Funktion sein, die in vordefiniert istvector Klasse .

z.B

array[5]={1,2,3,4,5};

vector<int> v;
v.assign(array, array+5); // 5 is size of array.

2
Entspricht der Verwendung des Ctors, die vor etwa sieben Jahren in bestehenden Antworten erwähnt wurde. Fügt nichts hinzu ...
Leichtigkeitsrennen im Orbit
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.