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?


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

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

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.


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


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

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

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.


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

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

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.



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


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.


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

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

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


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)

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.


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!


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

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>

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.

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 

4

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

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

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.


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

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ą).


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


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

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;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.