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


611

Ich kann ein Array erstellen und wie folgt initialisieren:

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

Wie erstelle ich ein std::vectorund initialisiere es ähnlich elegant?

Der beste Weg, den ich kenne, ist:

std::vector<int> ints;

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

Gibt es einen besseren Weg?


1
Wenn Sie die Größe von Ints nach der Initialisierung nicht ändern möchten, sollten Sie das Array tr1 verwenden.
zr.

@zr, du hast mich neugierig gemacht ... wenn ich eine feste Größe brauchte, könnte ich dann nicht einfach alte Arrays selbst verwenden? Mit Blick auf tr1 Array jetzt ...
Agnel Kurian

2
tr1::arrayist nützlich, weil gewöhnliche Arrays nicht die Schnittstelle von STL-Containern bieten
Manuel

Der Titel wurde geändert, um dies explizit zu einer C ++ 03-Frage zu machen. Es schien einfacher zu sein, als alle Antworten durchzugehen und zu korrigieren, um mit dem neuen Standard C ++ Sinn zu machen.
TED

Antworten:


548

Eine Methode wäre, das Array zum Initialisieren des Vektors zu verwenden

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

7
@Agnel Es funktioniert gut ohne staticoder const, aber beide machen es expliziter, wie es verwendet werden soll, und ermöglichen dem Compiler, zusätzliche Optimierungen vorzunehmen.
Yacoby

68
Ich habe das nicht heruntergestuft, aber ich war versucht. Hauptsächlich, weil Sie dadurch fast nichts sparen, wenn Sie nur das initialisierte Array verwenden. Das ist jedoch wirklich die Schuld von C ++, nicht deine.
Ted

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

13
sizeof (array) ist eine der wenigen Ausnahmen, mit denen die Gesamtgröße der Elemente des Arrays und NICHT die arr-Zeigerdimension ermittelt werden kann. Im Grunde genommen verwendet er also einen Vektor (pointer_to_first_element, pointer_to_first_element + size_in_bytes_of_the_whole_array / size_of_one_element), der heißt: vector (pointer_to_first_element, pointer_after_final_element). Der Typ ist bereits mit dem <int> angegeben, sodass der Vektor weiß, wie viel ein Element ist. Denken Sie daran, dass Iteratoren als Zeiger behandelt werden können, sodass Sie im Grunde genommen den Vektorkonstruktor (Iteratorbeginn, Iteratorende) verwenden
Johnny Pauling,

11
@TED: Manchmal müssen Sie den resultierenden Vektor ändern. Beispielsweise müssen Sie möglicherweise immer einige Standardparameter haben und manchmal einige angepasste hinzufügen.
DarkWanderer

641

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

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

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

Alternativ verwendet die Boost.Assign- Bibliothek Nicht- Makromagie , um Folgendes 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;

Denken Sie jedoch daran, dass dies einen gewissen Overhead hat (im Grunde genommen wird list_ofein std::dequeunter der Haube erstellt), sodass Sie für leistungskritischen Code besser dran sind, wie Yacoby sagt.


Da Vektoren sich selbst dimensionieren, wäre es in Ordnung, sie auch als leer zu initialisieren? Wie im Konstruktor : this->vect = {};?
Azurespot

3
@ Azurespot Sie können es einfach initialisieren, und es wird leer sein:std::vector<T> vector;
Luke

2
Nur für den Fall, dass jemand neugierig ist std::vector<int> v = {1, 2, 3, 4};, werden Vektoren initializer list constructorfür diese Art der Initialisierung aufgerufen. Das Dokument finden Sie im C++ 11Abschnitt .
Simomo

103

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

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

Die alte Art, ein Array mit variabler Länge zu durchlaufen oder zu verwenden, sizeof()ist für die Augen wirklich schrecklich und in Bezug auf den mentalen Overhead völlig unnötig. Yuck.


2
Fairerweise war dies ursprünglich eine C ++ 03-Frage, aber ich hoffe, dass Menschen / Unternehmen die neuen Standards übernehmen. C ++ benötigt weiterhin eine Array-Implementierung mit variabler Länge (VLA) in der Standardbibliothek, ähnlich wie in Eigen und Boost.
Adam Erickson

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

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

77

In C ++ 0x können Sie dies genauso tun wie mit einem Array, jedoch nicht im aktuellen Standard.

Mit nur Sprachunterstützung können Sie 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önnen Sie Boost :: Assignment ausprobieren:

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

So vermeiden Sie die Hardcodierung der Größe eines Arrays:

// 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))

Natürlich habe ich nicht abgelehnt, aber ich habe trotzdem eine Frage: Wann ist die Größe eines Arrays keine Konstante für die Kompilierungszeit? Dh in welchen Fällen würden Sie die erste Lösung in Ihrem zweiten Snippet im Gegensatz zur dritten verwenden?
Manuel

4
@Manuel, die Größe des Arrays ist Teil des Typs und als solche eine Kompilierungszeitkonstante. Jetzt verwendet Option 1 diese Kompilierungszeitkonstante 'N' als Rückgabewert für eine Funktion. Die Rückgabe einer Funktion ist keine Kompilierungszeit, sondern ein Laufzeitwert, auch wenn er wahrscheinlich als konstanter Wert am Ort des Aufrufs eingefügt wird. Der Unterschied ist, dass Sie nicht tun int another[size_of_array(array)]können:, während Sie tun können int another[ARRAY_SIZE(array)].
David Rodríguez - Dribeas

1
In Option 3: Ich verstehe nicht wirklich, was Sie mit "deklariert, undefiniert" meinen? Die Variable benötigt also keinen zusätzlichen Speicher?
To1ne

1
@ To1ne das ist eigentlich eine Funktionsdeklaration, keine Variable. Der Grund oder die Definition dafür ist, dass wir die Funktion eigentlich nur für den sizeofAusdruck benötigen, für den keine Definition erforderlich ist. Während Sie tatsächlich eine Definition bereitstellen können, würde die statische Zuweisung eines Arrays und die Rückgabe eines Verweises darauf erforderlich sein, um es richtig zu machen, und die nächste Frage wäre, was als Werte für das Array sinnvoll wäre. (Beachten Sie auch, dass dies ein Array pro Typ / Größe-Kombination der Instanziierungen der Funktion bedeutet!) Da dies keine sinnvolle Verwendung ist, würde ich es lieber vermeiden.
David Rodríguez - Dribeas

1
@mhd: Sie können kein leeres Array in der Sprache erstellen. 'int arr [0] = {};' ist kein gültiger C ++ - Code. Sie haben jedoch Recht, dass Sie unterschiedliche Konstrukte verwenden müssen, wenn Sie einen leeren Vektor und einen nicht leeren Vektor initialisieren möchten. Seit C ++ 11 ist dies kein Problem, da Sie den Initialisierungslistenkonstruktor
David Rodríguez - dribeas

61

In C ++ 11:

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

Verwenden 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);

Verwenden der Boost-Zuweisung:

#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 Vektorinitialisierermakro:

#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);

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

54

Ich dachte nur, ich würde meine $ 0,02 einwerfen. Ich neige dazu, dies zu erklären:

template< typename T, size_t N >
std::vector<T> makeVector( const T (&data)[N] )
{
    return std::vector<T>(data, data+N);
}

irgendwo in einem Utility-Header und dann ist alles, was benötigt wird:

const double values[] = { 2.0, 1.0, 42.0, -7 };
std::vector<double> array = makeVector(values);

Aber ich kann nicht auf C ++ 0x warten. Ich stecke fest, weil mein Code auch in Visual Studio kompiliert werden muss. Boo.


1
Diese Technik kann auch verwendet werden, um eine Funktion zu überladen, um ein Array mit typisierter Größe zu akzeptieren.
Andres Riofrio

4
Können Sie den const T (&data)[N]Teil erklären ? Wie wird die Größe des Arrays in Ihrem Anruf abgeleitet makeVector(values)?
Patryk

36

Vor C ++ 11:

Methode 1 =>

vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));
vector<int>v;

Methode 2 =>

 v.push_back(SomeValue);

Ab C ++ 11 ist ebenfalls möglich

vector<int>v = {1, 3, 5, 7};

28

Beginnen mit:

int a[] = {10, 20, 30}; //i'm assuming a is just a placeholder

Wenn Sie keinen C ++ 11-Compiler haben und keinen Boost verwenden möchten:

const int a[] = {10, 20, 30};
const std::vector<int> ints(a,a+sizeof(a)/sizeof(int)); //make it const if you can

Wenn Sie keinen C ++ 11-Compiler haben und Boost verwenden können:

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

Wenn Sie einen C ++ 11-Compiler haben:

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

22

Zur Vektorinitialisierung -

vector<int> v = {10,20,30}

kann durchgeführt werden, wenn Sie einen C ++ 11-Compiler haben.

Andernfalls können Sie ein Array der Daten haben und dann eine for-Schleife verwenden.

int array[] = {10,20,30}
for(unsigned int i=0; i<sizeof(array)/sizeof(array[0]); i++)
{
     v.push_back(array[i]);
}

Abgesehen von diesen gibt es verschiedene andere Möglichkeiten, die oben unter Verwendung von Code beschrieben wurden. Meiner Meinung nach sind diese Methoden leicht zu merken und schnell zu schreiben.



16

Ich baue meine eigene Lösung mit va_arg. Diese Lösung ist C ++ 98-kompatibel.

#include <cstdarg>
#include <iostream>
#include <vector>

template <typename T>
std::vector<T> initVector (int len, ...)
{
  std::vector<T> v;
  va_list vl;
  va_start(vl, len);
  for (int i = 0; i < len; ++i)
    v.push_back(va_arg(vl, T));
  va_end(vl);
  return v;
}

int main ()
{
  std::vector<int> v = initVector<int> (7,702,422,631,834,892,104,772);
  for (std::vector<int>::const_iterator it = v.begin() ; it != v.end(); ++it)
    std::cout << *it << std::endl;
  return 0;
}

Demo


14

Wenn Ihr Compiler Variadic-Makros unterstützt (was für die meisten modernen Compiler gilt), können Sie das folgende Makro verwenden, um die Vektorinitialisierung in einen Einzeiler umzuwandeln :

#define INIT_VECTOR(type, name, ...) \
static const type name##_a[] = __VA_ARGS__; \
vector<type> name(name##_a, name##_a + sizeof(name##_a) / sizeof(*name##_a))

Mit diesem Makro können Sie einen initialisierten Vektor mit folgendem Code definieren:

INIT_VECTOR(int, my_vector, {1, 2, 3, 4});

Dies würde einen neuen Ints-Vektor mit dem Namen my_vector mit den Elementen 1, 2, 3, 4 erstellen.


13

Wenn Sie Boost nicht verwenden möchten, aber Syntax wie genießen möchten

std::vector<int> v;
v+=1,2,3,4,5;

Fügen Sie einfach diesen Codeabschnitt hinzu

template <class T> class vector_inserter{
public:
    std::vector<T>& v;
    vector_inserter(std::vector<T>& v):v(v){}
    vector_inserter& operator,(const T& val){v.push_back(val);return *this;}
};
template <class T> vector_inserter<T> operator+=(std::vector<T>& v,const T& x){
    return vector_inserter<T>(v),x;
}

1
Ich konnte nicht herausfinden, wie dieser Code verwendet wird, aber er sieht interessant aus.
Daniel Buckmaster

Es ist wie einer der obigen Kommentare. Überladen Sie einfach + = und Kommaoperator. Zur Verdeutlichung Klammern setzen: ((((v+=1),2),3),4),5) So funktioniert es: Zuerst wird vector<T> += Tein vector_inserter zurückgegeben, vider den ursprünglichen Vektor einkapselt, und dann vi,TT zum ursprünglichen Vektor hinzugefügt, der ihn vieinkapselt und selbst zurückgibt , damit wir es vi,Terneut tun können.
Piti Ongmongkolkul

Dieser Code hat auf gcc 4.2.1 nicht richtig funktioniert. Ich denke, weil der Verweis auf eine lokale Variable innerhalb des Operators + = zurückgegeben wird, aber die Idee ist ausgezeichnet. Ich habe Code bearbeitet und es erscheint ein weiterer Kopierkonstruktor. Fluss ist jetzt -> + = -> ctor -> Komma -> Kopie -> dtor -> Komma ...... -> Komma -> dtor.
Yevhen

Ich hätte wahrscheinlich << anstelle von + = überladen. Zumindest << hat bereits vage Nebenwirkungsregeln wegen Bitverschiebungen und
Cout

11

In C ++ 11:

static const int a[] = {10, 20, 30};
vector<int> vec (begin(a), end(a));

21
Wenn Sie bereits C ++ 11 verwenden, können Sie sich auch für den direkten Ansatz entscheiden - vector<int> arr = {10, 20, 30};.
Bernhard Barker

Eigentlich hatte ich ein eingehendes int [] (etwas C lib) und wollte in einen Vektor (C ++ lib) pushen. Diese Antwort hat geholfen, der Rest nicht ;-)
Nebula

10

Sie können dies mit boost :: assign tun.

vector<int> values;  
values += 1,2,3,4,5,6,7,8,9;

Detail hier


19
Ich habe seit langer Zeit keinen schlimmeren Fall von Überlastung durch Bediener gesehen. Ist die +=dort anheften 1,2,3,4 .. bis zum Ende der Werte, oder tut es addieren 1 zum ersten Element, 2 mit dem zweiten Element, 3 mit dem dritten Element (wie Syntax wie diese sollten in Matlab wie Sprachen)
Bobobobo

10

Eine neuere doppelte Frage hat diese Antwort von Viktor Sehr . Für mich ist es kompakt, optisch ansprechend (es sieht so aus, als würden Sie die Werte "verschieben"), erfordert kein C ++ 11 oder ein Modul eines Drittanbieters und vermeidet die Verwendung einer zusätzlichen (geschriebenen) Variablen. Im Folgenden wird beschrieben, wie ich es mit einigen Änderungen verwende. Ich werde möglicherweise in Zukunft die Funktion von vector und / oder va_arg erweitern.


// Based on answer by "Viktor Sehr" on Stack Overflow
// https://stackoverflow.com/a/8907356
//
template <typename T>
class mkvec {
public:
    typedef mkvec<T> my_type;
    my_type& operator<< (const T& val) {
        data_.push_back(val);
        return *this;
    }
    my_type& operator<< (const std::vector<T>& inVector) {
        this->data_.reserve(this->data_.size() + inVector.size());
        this->data_.insert(this->data_.end(), inVector.begin(), inVector.end());
        return *this;
    }
    operator std::vector<T>() const {
        return data_;
    }
private:
    std::vector<T> data_;
};

std::vector<int32_t>    vec1;
std::vector<int32_t>    vec2;

vec1 = mkvec<int32_t>() << 5 << 8 << 19 << 79;  
// vec1 = (5,8,19,79)
vec2 = mkvec<int32_t>() << 1 << 2 << 3 << vec1 << 10 << 11 << 12;  
// vec2 = (1,2,3,5,8,19,79,10,11,12)

7

Die folgenden Methoden können verwendet werden, um den Vektor in c ++ zu initialisieren.

  1. int arr[] = {1, 3, 5, 6}; vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));

  2. vector<int>v; v.push_back(1); v.push_back(2); v.push_back(3); und so weiter

  3. vector<int>v = {1, 3, 5, 7};

Der dritte ist nur ab C ++ 11 zulässig.


5

Hier gibt es viele gute Antworten, aber da ich vor dem Lesen selbstständig zu meinen eigenen Antworten gekommen bin, dachte ich mir, ich würde meine sowieso hier hochwerfen ...

Hier ist eine Methode, die ich dafür verwende und die universell über Compiler und Plattformen hinweg funktioniert:

Erstellen Sie eine Struktur oder Klasse als Container für Ihre Objektsammlung. Definieren Sie eine Operatorüberladungsfunktion für <<.

class MyObject;

struct MyObjectList
{
    std::list<MyObject> objects;
    MyObjectList& operator<<( const MyObject o )
    { 
        objects.push_back( o );
        return *this; 
    }
};

Sie können Funktionen erstellen, die Ihre Struktur als Parameter verwenden, z.

someFunc( MyObjectList &objects );

Dann können Sie diese Funktion folgendermaßen aufrufen:

someFunc( MyObjectList() << MyObject(1) <<  MyObject(2) <<  MyObject(3) );

Auf diese Weise können Sie eine Sammlung von Objekten mit dynamischer Größe erstellen und an eine Funktion in einer einzigen klaren Linie übergeben!


4

Wenn Sie etwas in derselben allgemeinen Reihenfolge wie Boost :: Assign möchten, ohne eine Abhängigkeit von Boost zu erstellen, ist Folgendes zumindest vage ähnlich:

template<class T>
class make_vector {
    std::vector<T> data;
public:
    make_vector(T const &val) { 
        data.push_back(val);
    }

    make_vector<T> &operator,(T const &t) {
        data.push_back(t);
        return *this;
    }

    operator std::vector<T>() { return data; }
};

template<class T> 
make_vector<T> makeVect(T const &t) { 
    return make_vector<T>(t);
}

Ich wünschte, die Syntax für die Verwendung wäre sauberer, aber es ist immer noch nicht besonders schrecklich:

std::vector<int> x = (makeVect(1), 2, 3, 4);

4
typedef std::vector<int> arr;

arr a {10, 20, 30};       // This would be how you initialize while defining

So kompilieren Sie:

clang++ -std=c++11 -stdlib=libc++  <filename.cpp>

Frage Staaten C ++ 03 (nicht 11)
Mike P

1
Ich denke, es wurde nicht 03 angegeben, als ich darauf antwortete. Ich erinnere mich aber nicht perfekt. Es ist jedoch immer noch eine nützliche Antwort für jemanden, der nach einer schnellen Lösung sucht.
Shaveenk

4
// Before C++11
// I used following methods:

// 1.
int A[] = {10, 20, 30};                              // original array A

unsigned sizeOfA = sizeof(A)/sizeof(A[0]);           // calculate the number of elements

                                                     // declare vector vArrayA,
std::vector<int> vArrayA(sizeOfA);                   // make room for all
                                                     // array A integers
                                                     // and initialize them to 0 

for(unsigned i=0; i<sizeOfA; i++)
    vArrayA[i] = A[i];                               // initialize vector vArrayA


//2.
int B[] = {40, 50, 60, 70};                          // original array B

std::vector<int> vArrayB;                            // declare vector vArrayB
for (unsigned i=0; i<sizeof(B)/sizeof(B[0]); i++)
    vArrayB.push_back(B[i]);                         // initialize vArrayB

//3.
int C[] = {1, 2, 3, 4};                              // original array C

std::vector<int> vArrayC;                            // create an empty vector vArrayC
vArrayC.resize(sizeof(C)/sizeof(C[0]));              // enlarging the number of 
                                                     // contained elements
for (unsigned i=0; i<sizeof(C)/sizeof(C[0]); i++)
     vArrayC.at(i) = C[i];                           // initialize vArrayC


// A Note:
// Above methods will work well for complex arrays
// with structures as its elements.

4

Wenn das Array ist:

int arr[] = {1, 2, 3};
int len = (sizeof(arr)/sizeof(arr[0])); // finding length of array
vector < int > v;
std:: v.assign(arr, arr+len); // assigning elements from array to vector 

4

Es ist sehr praktisch, beim Schreiben eines Tests einen Vektor inline zu erstellen, ohne eine Variable zu definieren, zum Beispiel:

assert(MyFunction() == std::vector<int>{1, 3, 4}); // <- this.

3

Im Zusammenhang damit können Sie Folgendes verwenden, wenn Sie einen Vektor vollständig für eine schnelle Anweisung bereit haben möchten (z. B. sofort an eine andere Funktion übergeben):

#define VECTOR(first,...) \
   ([](){ \
   static const decltype(first) arr[] = { first,__VA_ARGS__ }; \
   std::vector<decltype(first)> ret(arr, arr + sizeof(arr) / sizeof(*arr)); \
   return ret;})()

Beispielfunktion

template<typename T>
void test(std::vector<T>& values)
{
    for(T value : values)
        std::cout<<value<<std::endl;
}

Beispiel verwenden

test(VECTOR(1.2f,2,3,4,5,6));

Seien Sie jedoch vorsichtig mit dem Dekltyp, stellen Sie jedoch sicher, dass der erste Wert genau Ihren Wünschen entspricht.


3

Es gibt verschiedene Möglichkeiten, einen Vektor fest zu codieren. Ich werde einige Möglichkeiten teilen:

  1. Initialisierung durch einzelnes Verschieben von Werten
// Create an empty vector 
    vector<int> vect;  

    vect.push_back(10); 
    vect.push_back(20); 
    vect.push_back(30); 
  1. Initialisieren wie Arrays
vector<int> vect{ 10, 20, 30 };
  1. Initialisierung von einem Array
    int arr[] = { 10, 20, 30 }; 
    int n = sizeof(arr) / sizeof(arr[0]); 

    vector<int> vect(arr, arr + n); 
  1. Initialisierung von einem anderen Vektor
    vector<int> vect1{ 10, 20, 30 }; 

    vector<int> vect2(vect1.begin(), vect1.end()); 

2

"Wie erstelle ich einen STL-Vektor und initialisiere ihn wie oben beschrieben? Was ist der beste Weg, dies mit minimalem Schreibaufwand zu tun?"

Der einfachste Weg, einen Vektor zu initialisieren, während Sie Ihr integriertes Array initialisiert haben, ist die Verwendung einer Initialisierungsliste, die in C ++ 11 eingeführt wurde .

// Initializing a vector that holds 2 elements of type int.
Initializing:
std::vector<int> ivec = {10, 20};


// The push_back function is more of a form of assignment with the exception of course
//that it doesn't obliterate the value of the object it's being called on.
Assigning
ivec.push_back(30);

ivec ist 3 Elemente groß, nachdem Assigning (beschriftete Anweisung) ausgeführt wurde.


In ähnlichen Zeilen versuche ich, die Karte zu initialisieren. Std :: map <int, bool> catinfo = {{1, false}}; Aber dann erhalten Sie diesen Fehler Fehler: In C ++ 98 muss 'catinfo' vom Konstruktor initialisiert werden, nicht von '{...}'
pdk

2

B. Stroustrup beschreibt in 16.2.10 Selfreference auf Seite 464 in der C ++ 11-Ausgabe des Prog eine gute Möglichkeit, Operationen zu verketten . Lang. Dabei gibt eine Funktion eine Referenz zurück, die hier in einen Vektor geändert wurde. Auf diese Weise können Sie verketten, v.pb(1).pb(2).pb(3);aber es kann zu viel Arbeit für solch kleine Gewinne sein.

#include <iostream>
#include <vector>

template<typename T>
class chain
{
private:
    std::vector<T> _v;
public:
    chain& pb(T a) {
        _v.push_back(a);
        return *this;
    };
    std::vector<T> get() { return _v; };
};

using namespace std;

int main(int argc, char const *argv[])
{
    chain<int> v{};

    v.pb(1).pb(2).pb(3);

    for (auto& i : v.get()) {
        cout << i << endl;
    }

    return 0;
}

1
2
3


Die Gürteltierbibliothek tut dies für die Matrixinitialisierung, verwendet jedoch den Operator << anstelle einer benannten Funktion: arma.sourceforge.net/docs.html#element_initialisation
Agnel Kurian

0

Der einfachste und ergonomischste Weg (mit C ++ 11 oder höher):

auto my_ints = {1,2,3};

0

Falls Sie es in Ihrer eigenen Klasse haben möchten:

#include <initializer_list>
Vector<Type>::Vector(std::initializer_list<Type> init_list) : _size(init_list.size()),
_capacity(_size),
_data(new Type[_size])
{
    int idx = 0;
    for (auto it = init_list.begin(); it != init_list.end(); ++it)
        _data[idx++] = *it;
}
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.