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?

Agnel Kurian
quelle
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
Dies wird als Listeninitialisierung bezeichnet .
Alan Dawkins

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]) );
Yacoby
quelle
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.

Manuel
quelle
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.

Adam Erickson
quelle
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))
David Rodríguez - Dribeas
quelle
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);
mbells
quelle
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.

M. Tibbits
quelle
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};
AJ
quelle
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};
Carl
quelle
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.

Tush_08
quelle
21

Der einfachste Weg ist:

vector<int> ints = {10, 20, 30};
Paul Baltescu
quelle
4
Welcher Compiler? Verwenden Sie hier C ++ 11?
Agnel Kurian
g ++ 4.6.3 mit -std = c ++ 0x.
Paul Baltescu
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

aloisdg wechselt zu codidact.com
quelle
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.

Matt Ball
quelle
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;
}
Piti Ongmongkolkul
quelle
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));
BufBills
quelle
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

f4.
quelle
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)
Othermusketeer
quelle
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.

Jay
quelle
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!

BuvinJ
quelle
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);
Jerry Sarg
quelle
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>
rasieren
quelle
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.
sg7
quelle
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 
FaridLU
quelle
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.
Daniel Stracaboško
quelle
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.

Josh
quelle
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()); 
Anil Gupta
quelle
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.

user2103487
quelle
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

kometen
quelle
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};
nz_21
quelle
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;
}
NixoN
quelle