Jaki jest najprostszy sposób na zainicjowanie standardowego pliku std :: vector za pomocą elementów zakodowanych na stałe?

611

Mogę utworzyć tablicę i zainicjować ją w następujący sposób:

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

Jak utworzyć std::vectori zainicjować go podobnie elegancko?

Najlepszy sposób, jaki znam to:

std::vector<int> ints;

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

Czy jest lepszy sposób?

Agnel Kurian
źródło
1
jeśli nie zamierzasz zmieniać rozmiaru ints po inicjalizacji, rozważ użycie tablicy tr1.
zr.
@ zr, masz mnie ciekawy ... gdybym potrzebował stałego rozmiaru, czy nie mógłbym sam użyć zwykłych starych tablic? Patrząc teraz na tablicę tr1 ...
Agnel Kurian
2
tr1::arrayjest użyteczny, ponieważ zwykłe tablice nie zapewniają interfejsu kontenerów STL
Manuel
Zmieniono tytuł, aby jawnie było to pytanie w C ++ 03. Wydawało się to łatwiejsze niż przeglądanie i ustalanie wszystkich odpowiedzi, które mają sens w nowym standardowym języku C ++.
TED
Nazywa się to inicjalizacją listy .
Alan Dawkins,

Odpowiedzi:

548

Jedną z metod byłoby użycie tablicy do zainicjowania wektora

static const int arr[] = {16,2,77,29};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
Yacoby
źródło
7
@Agnel będzie działać dobrze bez staticlub const, jednak oboje uczynić go bardziej wyraźne, jak należy go stosować i pozwól kompilator podjąć dodatkowe optymalizacje.
Yacoby
68
Nie lekceważyłem tego, ale kusiło mnie. Głównie dlatego, że oszczędza to prawie nic poza samym użyciem zainicjowanej tablicy. Jednak to naprawdę wina C ++, a nie twoja.
TED
2
Czy możesz wyjaśnić, dlaczego używasz tych parametrów podczas definiowania wektora vec.
DomX23,
13
sizeof (tablica) jest jednym z niewielu wyjątków, który pozwala uzyskać całkowity rozmiar elementów tablicy, a NIE wymiar wskaźnika arr. Zasadniczo używa więc wektora (pointer_to_first_element, pointer_to_first_element + size_in_bytes_of_the_whole_array / size_of_one_element), czyli: vector (pointer_to_first_element, pointer_after_final_element). Typ podano już z <int>, więc wektor wie, ile kosztuje jeden element. Pamiętaj, że iteratory można traktować jako wskaźniki, więc zasadniczo używasz konstruktora wektorowego (początek iteratora, koniec iteratora)
Johnny Pauling
11
@TED: Czasami musisz zmodyfikować wynikowy wektor. Na przykład może być konieczne posiadanie pewnych parametrów domyślnych, a czasem dodanie do nich kilku dostosowanych.
DarkWanderer
640

Jeśli Twój kompilator obsługuje C ++ 11, możesz po prostu:

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

Jest to dostępne w GCC od wersji 4.4 . Niestety VC ++ 2010 wydaje się pozostawać w tyle pod tym względem.

Alternatywnie biblioteka Boost.Assign wykorzystuje magię inną niż makr, aby umożliwić:

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

Lub:

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

Należy jednak pamiętać, że wiąże się to z pewnym nakładem (w zasadzie list_ofkonstruuje się std::dequepod maską), więc w przypadku kodu o kluczowej wydajności lepiej byłoby robić tak, jak mówi Yacoby.

Manuel
źródło
Skoro wektory są samowyrównujące się, czy dobrze byłoby zainicjować je również jako puste? Jak w konstruktorze this->vect = {};:?
Azurespot
3
@Azurespot Możesz go po prostu zainicjować, a będzie pusty:std::vector<T> vector;
Luke
2
Na wypadek, gdyby ktoś był ciekawy std::vector<int> v = {1, 2, 3, 4};, wektor initializer list constructorzostanie wezwany do tego rodzaju inicjalizacji, jego dokumentację można znaleźć w C++ 11sekcji .
simomo
103

Jeśli możesz, użyj nowoczesnego sposobu C ++ [11,14,17, ...]:

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

Stary sposób zapętlania lub używania tablicy o zmiennej długości sizeof()jest naprawdę okropny dla oczu i całkowicie niepotrzebny z punktu widzenia obciążenia umysłowego. Fuj

Adam Erickson
źródło
2
Szczerze mówiąc, było to pierwotnie pytanie C ++ 03, ale mam nadzieję, że ludzie / firmy przyjmą nowe standardy. C ++ nadal wymaga implementacji tablicy zmiennej długości (VLA) w standardowej bibliotece podobnej do tej dostępnej w Eigen i Boost.
Adam Erickson,
Niestety takie podejście jest problematyczne w niektórych przypadkach, np . Open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467 . Fuj
Wyścigi lekkości na orbicie
Jeśli twoja „inicjalizacja listy agregacji z obiektu tego samego typu” jest twoją rzeczą, prawdopodobnie w twojej bazie kodu są większe problemy ... Nie mogę znaleźć żadnej aplikacji, w której uzasadniałoby to problemy z debugowaniem.
Adam Erickson,
77

W C ++ 0x będziesz mógł to zrobić w taki sam sposób jak w przypadku tablicy, ale nie w obecnym standardzie.

Tylko z obsługą języka możesz użyć:

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

Jeśli możesz dodać inne biblioteki, możesz spróbować boost :: assignment:

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

Aby uniknąć zakodowania na stałe rozmiaru tablicy:

// 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
źródło
Oczywiście nie przegłosowałem, ale i tak mam pytanie: kiedy rozmiar tablicy nie jest stałą czasową kompilacji? To znaczy, w jakich przypadkach użyłbyś pierwszego rozwiązania w swoim drugim fragmencie w przeciwieństwie do trzeciego?
Manuel
4
@Manuel, rozmiar tablicy jest częścią typu i jako taka jest stałą czasową kompilacji. Teraz opcja 1 wykorzystuje tę stałą czasową kompilacji „N” jako wartość zwracaną dla funkcji. Zwrot funkcji nie jest czasem kompilacji, ale wartością środowiska uruchomieniowego, nawet jeśli prawdopodobnie zostanie wstawiona jako stała wartość w miejscu wywołania. Różnica polega na tym, że nie możesz: int another[size_of_array(array)]podczas gdy możesz int another[ARRAY_SIZE(array)].
David Rodríguez - dribeas
1
W opcji 3: Naprawdę nie rozumiem, co masz na myśli przez „zadeklarowany, niezdefiniowany”? Więc zmienna nie zajmie dodatkowej pamięci?
To1ne
1
@ To1ne, które w rzeczywistości jest deklaracją funkcji, a nie zmienną. Powodem lub definicją jest to, że tak naprawdę nie chcemy funkcji dla niczego innego niż sizeofwyrażenie, które nie wymaga definicji. Chociaż faktycznie możesz podać definicję, wykonanie jej poprawnie wymagałoby statycznego przydzielenia tablicy i zwrócenia do niej odwołania, a następnym pytaniem byłoby, co byłoby sensowne jako wartości dla tablicy? (Zauważ też, że oznacza to jedną tablicę dla kombinacji typu / rozmiaru instancji funkcji!) Ponieważ nie jest to rozsądne zastosowanie, wolałbym go unikać.
David Rodríguez - dribeas
1
@mhd: Nie można zbudować pustej tablicy w języku. „int arr [0] = {};” nie jest poprawnym kodem C ++. Ale masz rację, że jeśli chcesz zainicjować pusty wektor i niepusty wektor, będziesz musiał użyć różnych konstrukcji. Od wersji C ++ 11 nie jest to problem, ponieważ można użyć konstruktora listy inicjalizacyjnej
David Rodríguez - dribeas,
61

W C ++ 11:

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

Korzystanie z listy ulepszeń:

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

Za pomocą boost przypisania:

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

Konwencjonalny STL:

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

Konwencjonalny STL z ogólnymi makrami:

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

Konwencjonalny STL z makrem inicjatora wektora:

#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);
dzwonki
źródło
2
C ++ 11 również wspiera std::begini std::endna matrycy, a więc wektor może być również inicjowane podobne static const int arr[] = {10,20,30}; vector<int> vec(begin(arr), end(arr));.
Jaege
54

Pomyślałem, że wrzucę moje 0,02 $. Oświadczam, że:

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

gdzieś w nagłówku narzędzia, a następnie wszystko, co jest wymagane, to:

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

Ale nie mogę się doczekać C ++ 0x. Utknąłem, ponieważ mój kod musi się również kompilować w programie Visual Studio. Gwizd.

M. Tibbits
źródło
1
Tej techniki można również użyć do przeciążenia funkcji, aby zaakceptować tablicę o wpisanym rozmiarze.
Andres Riofrio,
4
Czy możesz wyjaśnić tę const T (&data)[N]część? Jak oblicza się rozmiar tablicy w twoim połączeniu makeVector(values)?
Patryk
36

Przed C ++ 11:

Metoda 1 =>

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

Metoda 2 =>

 v.push_back(SomeValue);

C ++ 11 i nowsze wersje są również możliwe

vector<int>v = {1, 3, 5, 7};
AJ
źródło
28

Począwszy od:

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

Jeśli nie masz kompilatora C ++ 11 i nie chcesz używać boost:

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

Jeśli nie masz kompilatora C ++ 11 i możesz użyć boost:

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

Jeśli masz kompilator C ++ 11:

const std::vector<int> ints = {10,20,30};
Carl
źródło
22

Do inicjalizacji wektorów -

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

można to zrobić, jeśli masz kompilator c ++ 11.

W przeciwnym razie możesz mieć tablicę danych, a następnie użyć pętli for.

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

Oprócz nich istnieją różne inne sposoby opisane powyżej przy użyciu kodu. Moim zdaniem te sposoby są łatwe do zapamiętania i szybkie do napisania.

Tush_08
źródło
21

Najłatwiej to zrobić:

vector<int> ints = {10, 20, 30};
Paul Baltescu
źródło
4
Który kompilator? Czy używasz tutaj C ++ 11?
Agnel Kurian
g ++ 4.6.3 z -std = c ++ 0x.
Paul Baltescu
16

Buduję własne rozwiązanie za pomocą va_arg. To rozwiązanie jest zgodne z C ++ 98.

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

Próbny

aloisdg przechodzi na codidact.com
źródło
14

Jeśli Twój kompilator obsługuje makra Variadic (co jest prawdą w przypadku większości współczesnych kompilatorów), możesz użyć następującego makra, aby zmienić inicjalizację wektorową w jednowierszową:

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

Za pomocą tego makra możesz zdefiniować zainicjowany wektor za pomocą kodu w następujący sposób:

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

Spowoduje to utworzenie nowego wektora int o nazwie my_vector z elementami 1, 2, 3, 4.

Matt Ball
źródło
13

Jeśli nie chcesz używać wzmocnienia, ale chcesz cieszyć się podobną składnią

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

po prostu dołącz ten fragment kodu

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
źródło
1
Nie byłem w stanie dowiedzieć się, jak korzystać z tego kodu, ale wygląda interesująco.
Daniel Buckmaster
To tak, jak powiedział jeden z powyższych komentarzy. Tylko przeciążenie + = i przecinek operatora. Umieszczanie nawiasów dla przejrzystości: ((((v+=1),2),3),4),5) Oto jak to działa: Najpierw vector<T> += Tzwraca vector_inserter pozwala wywołać go, viktóry otacza oryginalny wektor, a następnie vi,Tdodać T do oryginalnego wektora, który viotacza i zwróć go, abyśmy mogli zrobić to vi,Tponownie.
Piti Ongmongkolkul
ten kod nie działał poprawnie na gcc 4.2.1. Myślę, że z powodu zwracania odwołania do zmiennej lokalnej wewnątrz operatora + =, ale pomysł jest doskonały. edytowałem kod i pojawia się jeszcze jeden konstruktor kopii. przepływ jest teraz -> + = -> ctor -> przecinek -> kopia -> dtor -> przecinek ...... -> przecinek -> dtor.
Jewhen
Prawdopodobnie przeciążę << zamiast + =. Przynajmniej << ma już niejasne reguły skutków ubocznych z powodu przesunięć bitów i cout
Speed8ump
11

W C ++ 11:

static const int a[] = {10, 20, 30};
vector<int> vec (begin(a), end(a));
BufBills
źródło
21
Jeśli używasz już C ++ 11, równie dobrze możesz przejść do bezpośredniego podejścia - vector<int> arr = {10, 20, 30};.
Bernhard Barker
Właściwie miałem przychodzące int [] (trochę C lib) i chciałem wcisnąć do wektora (C ++ lib). Ta odpowiedź pomogła, reszta nie ;-)
Mgławica
10

możesz to zrobić za pomocą boost :: przypisać.

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

szczegóły tutaj

f4.
źródło
19
Dawno nie widziałem gorszego przypadku nadużycia przez operatora. Czy dodaje +=on 1,2,3,4 .. na końcu wartości, czy dodaje 1 do 1. elementu, 2 do 2. elementu, 3 do 3. elementu (tak jak w składni takiej jak ta w MATLAB- jak języki)
bobobobo
10

Nowsza duplikat pytanie ma tę odpowiedź przez Wiktora Sehr . Dla mnie jest kompaktowy, atrakcyjny wizualnie (wygląda na to, że „wpychasz” wartości), nie wymaga c ++ 11 ani modułu innej firmy i unika używania dodatkowej (zapisanej) zmiennej. Poniżej opisuję, jak go używam z kilkoma zmianami. Mogę przejść do rozszerzenia funkcji wektora i / lub va_arg w przyszłym intead.


// 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
źródło
7

Poniższych metod można użyć do zainicjowania wektora w c ++.

  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); i tak dalej

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

Trzeci jest dozwolony tylko w C ++ 11 i późniejszych.

Sójka
źródło
5

Jest tu wiele dobrych odpowiedzi, ale ponieważ niezależnie doszedłem do siebie przed przeczytaniem tego, pomyślałem, że i tak podrzucę tu mój ...

Oto metoda, której używam do tego, która będzie działać uniwersalnie na kompilatorach i platformach:

Utwórz struct lub klasę jako kontener dla swojej kolekcji obiektów. Zdefiniuj funkcję przeciążenia operatora dla <<.

class MyObject;

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

Możesz tworzyć funkcje, które przyjmują strukturę jako parametr, np .:

someFunc( MyObjectList &objects );

Następnie możesz wywołać tę funkcję w następujący sposób:

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

W ten sposób możesz budować i przekazywać dynamicznie wielkościowy zbiór obiektów do funkcji w jednym czystym wierszu!

BuvinJ
źródło
4

Jeśli chcesz mieć coś w tej samej ogólnej kolejności co Boost :: przypisanie bez tworzenia zależności od Boost, poniższe są co najmniej niejasno podobne:

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

Chociaż chciałbym, aby składnia za jego użycie była czystsza, nadal nie jest szczególnie okropna:

std::vector<int> x = (makeVect(1), 2, 3, 4);
Jerry Coffin
źródło
4
typedef std::vector<int> arr;

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

Do kompilacji użyj:

clang++ -std=c++11 -stdlib=libc++  <filename.cpp>
shaveenk
źródło
Pytanie brzmi C ++ 03 (nie 11)
Mike P
1
Myślę, że nie określił 03, kiedy odpowiedziałem na to. Nie pamiętam jednak doskonale. Jednak nadal jest to przydatna odpowiedź dla kogoś, kto szuka szybkiego rozwiązania.
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
źródło
4

Jeśli tablica to:

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
źródło
4

Wygodnie jest utworzyć wektor wstawiany bez definiowania zmiennej podczas pisania testu, na przykład:

assert(MyFunction() == std::vector<int>{1, 3, 4}); // <- this.
Daniel Stracaboško
źródło
3

Powiązane, możesz użyć następujących, jeśli chcesz, aby wektor był całkowicie gotowy do użycia w szybkiej instrukcji (np. Natychmiastowe przejście do innej funkcji):

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

przykładowa funkcja

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

przykładowe użycie

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

choć uważaj na rodzaj, upewnij się, że pierwsza wartość jest dokładnie taka, jak chcesz.

Josh
źródło
3

Istnieje wiele sposobów na zakodowanie wektora, podzielę się kilkoma sposobami:

  1. Inicjowanie poprzez przepychanie wartości jeden po drugim
// Create an empty vector 
    vector<int> vect;  

    vect.push_back(10); 
    vect.push_back(20); 
    vect.push_back(30); 
  1. Inicjowanie jak tablice
vector<int> vect{ 10, 20, 30 };
  1. Inicjowanie z tablicy
    int arr[] = { 10, 20, 30 }; 
    int n = sizeof(arr) / sizeof(arr[0]); 

    vector<int> vect(arr, arr + n); 
  1. Inicjalizacja z innego wektora
    vector<int> vect1{ 10, 20, 30 }; 

    vector<int> vect2(vect1.begin(), vect1.end()); 
Anil Gupta
źródło
2

„Jak utworzyć wektor STL i zainicjować go w powyższy sposób? Jak najlepiej to zrobić przy minimalnym wysiłku pisania?”

Najprostszym sposobem na zainicjowanie wektora po zainicjowaniu wbudowanej tablicy jest użycie listy inicjalizacyjnej, która została wprowadzona w C ++ 11 .

// 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 ma rozmiar 3 elementów po wykonaniu Przypisanie (instrukcja z etykietą).

użytkownik2103487
źródło
W podobnych wierszach próbuję zainicjować mapę, std :: map <int, bool> catinfo = {{1, false}}; Ale wtedy otrzymaj ten błąd: w C ++ 98 „catinfo” musi zostać zainicjowane przez konstruktora, a nie przez {{...}
pdk
2

B. Stroustrup opisuje dobry sposób łączenia operacji w 16.2.10 Odniesienie do siebie na stronie 464 w edycji C ++ 11 programu Prog. Lang. gdzie funkcja zwraca odwołanie, tutaj zmodyfikowane do wektora. W ten sposób możesz łączyć łańcuchy, v.pb(1).pb(2).pb(3);ale może to być zbyt wiele pracy dla tak małych zysków.

#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
źródło
Biblioteka armadillo robi to w celu inicjalizacji macierzy, ale używa operatora << zamiast nazwanej funkcji: arma.sourceforge.net/docs.html#element_initialisation
Agnel Kurian
0

Najprostszy, bardziej ergonomiczny sposób (z C ++ 11 lub nowszym):

auto my_ints = {1,2,3};
nz_21
źródło
0

Jeśli chcesz mieć to we własnej klasie:

#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
źródło