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.

Amir Saniyan
quelle

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.

Fred Foo
quelle
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 });
Dietmar Kühl
quelle
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)
Rafał Rawicki
quelle
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 )

Flexo
quelle
"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.
3251_ali
quelle
2
Entspricht der Verwendung des Ctors, die vor etwa sieben Jahren in bestehenden Antworten erwähnt wurde. Fügt nichts hinzu ...
Leichtigkeitsrennen im Orbit