713 Stimmen

Was ist der einfachste Weg, einen std::vector mit fest kodierten Elementen zu initialisieren?

Ich kann ein Array erstellen und es wie folgt initialisieren:

int a[] = {10, 20, 30};

Wie kann ich eine std::vector und sie ähnlich elegant initialisieren?

Das ist der beste Weg, den ich kenne:

std::vector<int> ints;

ints.push_back(10);
ints.push_back(20);
ints.push_back(30);

Gibt es einen besseren Weg?

1 Stimmen

Wenn Sie die Größe von ints nach der Initialisierung nicht ändern wollen, sollten Sie tr1 array verwenden.

1 Stimmen

@zr, Sie haben mich neugierig... wenn ich feste Größe benötigt, könnte ich nicht einfach alte Arrays selbst verwenden? Blick auf tr1 Array gerade jetzt...

2 Stimmen

tr1::array ist nützlich, weil gewöhnliche Arrays nicht die Schnittstelle von STL-Containern bieten

764voto

Manuel Punkte 12399

Wenn Ihr Compiler C++11 unterstützt, können Sie dies einfach tun:

std::vector<int> v = {1, 2, 3, 4};

Dies ist im GCC verfügbar ab Version 4.4 . Leider scheint VC++ 2010 in dieser Hinsicht hinterherzuhinken.

Alternativ dazu kann die Boost.Zuweisen Bibliothek verwendet Nicht-Makro-Magie, um das Folgende zu ermöglichen:

#include <boost/assign/list_of.hpp>
...
std::vector<int> v = boost::assign::list_of(1)(2)(3)(4);

Oder:

#include <boost/assign/std/vector.hpp>
using namespace boost::assign;
...
std::vector<int> v;
v += 1, 2, 3, 4;

Bedenken Sie jedoch, dass dies mit einem gewissen Aufwand verbunden ist (im Wesentlichen, list_of konstruiert eine std::deque unter der Haube), so dass Sie bei leistungsrelevantem Code besser vorgehen sollten, wie Yacoby sagt.

0 Stimmen

Da Vektoren sind selbst-Größe, wäre es in Ordnung, es als leer zu initialisieren zu? Wie im Konstruktor: this->vect = {}; ?

3 Stimmen

@Azurespot Sie können ihn einfach initialisieren, dann ist er leer: std::vector<T> vector;

2 Stimmen

Nur für den Fall, dass jemand neugierig ist auf std::vector<int> v = {1, 2, 3, 4}; , Vektor initializer list constructor wird für diese Art der Initialisierung aufgerufen, sein Dokument findet sich in der C++ 11 Abschnitt .

584voto

Yacoby Punkte 52756

Eine Methode wäre, das Array zur Initialisierung des Vektors zu verwenden

static const int arr[] = {16,2,77,29};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );

7 Stimmen

@Agnel Es geht auch ohne static o const Beide machen jedoch deutlicher, wie es verwendet werden sollte, und ermöglichen dem Compiler zusätzliche Optimierungen.

78 Stimmen

Ich habe es nicht heruntergeladen, aber ich war in Versuchung. Vor allem, weil dies spart Sie fast nichts über nur mit dem initialisierten Array an erster Stelle. Allerdings ist das wirklich C++'s Schuld, nicht Ihre.

2 Stimmen

Können Sie erklären, warum Sie diese Parameter bei der Definition des Vec-Vektors verwenden?

142voto

Adam Erickson Punkte 5415

Wenn Sie können, verwenden Sie die moderne C++[11,14,17,20,...] Methode:

std::vector<int> ints = {10, 20, 30};

Die alte Methode der Schleifenbildung über ein Array variabler Länge oder die Verwendung von sizeof() ist wirklich schrecklich für die Augen und völlig unnötig in Bezug auf den geistigen Aufwand. Igitt.

3 Stimmen

Fairerweise muss man sagen, dass dies ursprünglich eine C++03-Frage war, aber ich hoffe, dass die Leute/Unternehmen die neuen Standards übernehmen. C++ braucht immer noch eine Implementierung von Arrays variabler Länge (VLA) in der Standardbibliothek, ähnlich wie sie in Eigen und Boost verfügbar ist.

0 Stimmen

Leider ist dieser Ansatz in einigen Fällen problematisch, z. B. open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467 . Igitt.

0 Stimmen

Wenn "Listeninitialisierung eines Aggregats aus einem Objekt desselben Typs" Ihr Ding ist, gibt es wahrscheinlich größere Probleme in Ihrer Codebasis... Ich kann mir keine Anwendung vorstellen, bei der es die Debugging-Probleme rechtfertigen würde.

81voto

In C++0x können Sie dies auf die gleiche Weise wie bei einem Array tun, aber nicht im aktuellen Standard.

Sie können nur Sprachunterstützung verwenden:

int tmp[] = { 10, 20, 30 };
std::vector<int> v( tmp, tmp+3 ); // use some utility to avoid hardcoding the size here

Wenn Sie andere Bibliotheken hinzufügen können, könnten Sie boost::assignment ausprobieren:

vector<int> v = list_of(10)(20)(30);

Um die feste Kodierung der Größe eines Arrays zu vermeiden:

// option 1, typesafe, not a compile time constant
template <typename T, std::size_t N>
inline std::size_t size_of_array( T (&)[N] ) {
   return N;
}
// option 2, not typesafe, compile time constant
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))

// option 3, typesafe, compile time constant
template <typename T, std::size_t N>
char (&sizeof_array( T(&)[N] ))[N];    // declared, undefined
#define ARRAY_SIZE(x) sizeof(sizeof_array(x))

0 Stimmen

Natürlich habe ich nicht abgelehnt, aber ich habe trotzdem eine Frage: Wann ist die Größe eines Arrays keine Kompilierzeitkonstante? D.h., in welchen Fällen würden Sie die erste Lösung in Ihrem zweiten Schnipsel im Gegensatz zu der dritten Lösung verwenden?

0 Stimmen

+Stimme von meiner Seite. In C++0x konnte man eine constexpr der Option 1. Aber das wird dann auch nicht mehr genutzt :S

4 Stimmen

@Manuel, die Größe des Arrays ist Teil des Typs und als solche eine Kompilierzeitkonstante. Option 1 verwendet diese Kompilierzeitkonstante "N" als Rückgabewert für eine Funktion. Der Rückgabewert einer Funktion ist kein Kompilierzeit-, sondern ein Laufzeitwert, auch wenn er wahrscheinlich als konstanter Wert am Ort des Aufrufs eingefügt wird. Der Unterschied ist, dass Sie das nicht tun können: int another[size_of_array(array)] während Sie Folgendes tun können int another[ARRAY_SIZE(array)] .

80voto

mbells Punkte 3448

In C++11:

#include <vector>
using std::vector;
...
vector<int> vec1 { 10, 20, 30 };
// or
vector<int> vec2 = { 10, 20, 30 };

Verwendung von Boost list_of :

#include <vector>
#include <boost/assign/list_of.hpp>
using std::vector;
...
vector<int> vec = boost::assign::list_of(10)(20)(30);

Mit Boost zuweisen:

#include <vector>
#include <boost/assign/std/vector.hpp>
using std::vector;
...
vector<int> vec;
vec += 10, 20, 30;

Konventionelle STL:

#include <vector>
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );

Konventionelle STL mit generischen Makros:

#include <vector>
#define ARRAY_SIZE(ar) (sizeof(ar) / sizeof(ar[0])
#define ARRAY_END(ar) (ar + ARRAY_SIZE(ar))
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec (arr, ARRAY_END(arr));

Konventionelle STL mit einem Vektor-Initialisierungsmakro:

#include <vector>
#define INIT_FROM_ARRAY(ar) (ar, ar + sizeof(ar) / sizeof(ar[0])
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec INIT_FROM_ARRAY(arr);

5 Stimmen

C++11 unterstützt auch std::begin y std::end für Array, so dass ein Vektor auch wie folgt initialisiert werden kann static const int arr[] = {10,20,30}; vector<int> vec(begin(arr), end(arr)); .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X