Sabit kodlu elemanlarla bir std :: vector'u başlatmanın en kolay yolu nedir?


611

Bir dizi oluşturabilir ve bu şekilde başlatabilirim:

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

Nasıl std::vectorzarif bir a oluşturur ve başlatırım?

Bildiğim en iyi yol:

std::vector<int> ints;

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

Daha iyi bir yol var mı?


1
başlattıktan sonra ints boyutunu değiştirmeyecekseniz, tr1 dizisini kullanmayı düşünün.
zr.

@zr, merak ediyorsun ... sabit boyuta ihtiyacım olursa, düz eski dizileri kendileri kullanamaz mıydım? Şu anda tr1 dizisine bakıyoruz ...
Agnel Kurian

2
tr1::arrayyararlıdır çünkü sıradan diziler STL kapsayıcılarının arayüzünü sağlamaz
Manuel

Bunu açıkça bir C ++ 03 sorusu yapmak için başlığı değiştirdi. Yeni standart C ++ ile anlamlı olmak için tüm cevapları düzeltmekten ve düzeltmekten daha kolay görünüyordu.
TED

Yanıtlar:


548

Bir yöntem, vektörü başlatmak için diziyi kullanmak olacaktır.

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

7
@Agnel Olmadan staticveya iyi çalışacaktır const, ancak her ikisi de nasıl kullanılması gerektiği konusunda daha açık hale getirir ve derleyicinin ek optimizasyonlar yapmasına izin verir.
Yacoby

68
Bunu abartmadım, ama baştan çıkarıldım. Temelde bu sadece başlangıçta sadece dizi kullanarak neredeyse hiçbir şey kaydeder çünkü. Ancak, bu gerçekten C ++ 'ın hatası, senin değil.
TED

2
Vec vektörünü tanımlarken neden bu parametreleri kullandığınızı açıklayabilir misiniz?
DomX23

13
sizeof (dizi) dizi öğesinin toplam boyutunu ve arr işaretçisi boyutunu ALMAYI sağlayan birkaç istisnadan biridir. Temelde vektör (pointer_to_first_element, pointer_to_first_element + size_in_bytes_of_the_whole_array / size_of_one_element) yani vektör kullanıyor: vector (pointer_to_first_element, pointer_after_final_element). Tip zaten <int> ile verilir, bu nedenle vektör bir öğenin ne kadar olduğunu bilir. Yineleyicilerin işaretçi olarak ele alınabileceğini unutmayın, böylece temel olarak vektör (yineleyici başlangıcı, yineleyici sonu) yapıcısını kullanıyorsunuz
Johnny Pauling

11
@TED: Bazen ortaya çıkan vektörü değiştirmeniz gerekebilir. Örneğin, her zaman bazı varsayılan parametrelere sahip olmanız ve bazen bunlara özelleştirilmiş birkaç parametre eklemeniz gerekebilir.
DarkWanderer

641

Derleyiciniz C ++ 11'i destekliyorsa şunları yapabilirsiniz:

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

Bu, GCC'de 4.4 sürümünden itibaren mevcuttur . Ne yazık ki, VC ++ 2010 bu açıdan geride kalıyor gibi görünüyor.

Alternatif olarak, Boost.Assign kitaplığı aşağıdakilere izin vermek için makro olmayan büyü kullanır:

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

Veya:

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

Ancak bunun bazı ek yükleri olduğunu unutmayın (temelde, kaputun altında list_ofbir yapı oluşturur std::deque), bu nedenle performans açısından kritik kod için Yacoby'nin söylediği gibi yapmaktan daha iyi olur.


Vektörler kendi kendine boyutlandırıldığından, onu da boş olarak başlatmak uygun olur mu? Yapıcı içinde mi: this->vect = {};?
Azurespot

3
@Azurespot Sadece başlatabilirsiniz ve boş olacaktır:std::vector<T> vector;
Luke

2
Birisinin merak etmesi durumunda std::vector<int> v = {1, 2, 3, 4};, initializer list constructorbu tür bir başlatma için vektörler çağrılır, dokümanı C++ 11bölümde bulunabilir .
simomo

103

Yapabiliyorsanız, modern C ++ [11,14,17, ...] yolunu kullanın:

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

Değişken uzunlukta bir dizi üzerinde döngü yapmanın veya kullanmanın eski yolu sizeof(), gözler üzerinde gerçekten korkunçtur ve zihinsel yük açısından tamamen gereksizdir. Yuck.


2
Adil olmak gerekirse, bu aslında bir C ++ 03 sorusuydu, ancak umarım insanlar / şirketler yeni standartları benimser. C ++ hala standart kitaplıkta Eigen ve Boost'da bulunanlara benzer bir değişken uzunluklu dizi (VLA) uygulamasına ihtiyaç duyar.
Adam Erickson

Ne yazık ki, bu yaklaşım bazı durumlarda sorunludur, örneğin open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467 . Yuck.
Orbit'te Hafiflik Yarışları

"Aynı tür bir nesneden bir toplu liste başlatma" bir şey, muhtemelen kod temeli daha büyük sorunlar vardır ... Ben hata ayıklama sorunları haklı nereye hiçbir uygulama düşünebilirsiniz.
Adam Erickson

77

C ++ 0x ile bunu bir diziyle yaptığınız gibi yapabilirsiniz, ancak geçerli standartta yapamazsınız.

Yalnızca dil desteğiyle şunları kullanabilirsiniz:

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

Başka kütüphaneler ekleyebiliyorsanız boost :: assignment'ı deneyebilirsiniz:

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

Bir dizinin boyutunu kodlamaktan kaçınmak için:

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

Tabii ki downvote etmedim ama yine de bir sorum var: bir dizinin boyutu ne zaman derleme zamanı sabiti değil? Yani, hangi durumlarda ikinci kod parçanızdaki ilk çözümü üçüncü çözümün aksine kullanırsınız?
Manuel

4
@Manuel, dizinin boyutu türün bir parçasıdır ve bu nedenle derleme zaman sabitidir. Şimdi, seçenek 1, bir işlev için dönüş değeri olarak bu derleme zaman sabitini 'N' kullanır. Bir işlevin geri dönüşü derleme zamanı değil, büyük olasılıkla çağrı yerinde sabit değer olarak satır içine alınmış olsa bile, çalışma zamanı değeridir. Aradaki fark, yapamamanızdır: int another[size_of_array(array)]yapabilirsiniz int another[ARRAY_SIZE(array)].
David Rodríguez - dribeas

1
Seçenek 3'te: "Beyan, undefined" ile ne demek istediğini anlamıyorum? Yani değişken ek bellek almayacak mı?
Haziran'da To1ne

1
@ To1ne, aslında bir değişken değil, bir işlev bildirimidir. Bunun nedeni veya tanımlanması, aslında sizeofbir tanıma ihtiyaç duymayan ifadeden başka bir şey için işlevi istemememizdir . Aslında bir tanım sağlayabilirken, bunu doğru yapmak için bir dizinin statik olarak tahsis edilmesini ve ona bir referansın döndürülmesini gerektirecektir ve bir sonraki soru dizi için değer olarak ne mantıklı olacaktır? (Ayrıca, işlevin örneklerinin her tür / boyut kombinasyonu için bir dizi anlamına geldiğini unutmayın!) Bunun mantıklı bir kullanımı olmadığından, bundan kaçınmayı tercih ederim.
David Rodríguez - dribeas

1
@mhd: Dilde boş bir dizi oluşturamazsınız. 'int arr [0] = {};' geçerli C ++ kodu değil. Ancak, boş bir vektörü ve boş olmayan bir vektörü başlatmak istiyorsanız, farklı yapılar kullanmanız gerektiği konusunda haklısınız. C ++ 11 olduğundan, başlatıcı listesi yapıcısını kullanabileceğiniz için bu bir sorun değil
David Rodríguez - dribeas

61

C ++ 11'de:

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

Boost list_of işlevini kullanma:

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

Boost atamasını kullanma:

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

Geleneksel STL:

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

Genel makrolara sahip geleneksel STL:

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

Bir vektör başlatıcı makro ile geleneksel STL:

#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 de destek std::beginve std::enddizi için, böylece bir vektör gibi de başlatılabilir static const int arr[] = {10,20,30}; vector<int> vec(begin(arr), end(arr));.
Jaege

54

Sadece benim 0.02 $ benim atmak düşündüm. Bunu beyan etme eğilimindeyim:

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

bir yerde bir yardımcı program üstbilgisinde ve sonra gereken tek şey:

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

Ama C ++ 0x için sabırsızlanıyorum. Kodum da Visual Studio'da derlenmesi gerektiği için sıkıştım. Boo.


1
Bu teknik aynı zamanda, yazılan boyutlu bir diziyi kabul etmek üzere bir işlevi aşırı yüklemek için de kullanılabilir.
Andres Riofrio

4
Parçayı açıklayabilir misiniz const T (&data)[N]? Dizinin boyutu aramanızda makeVector(values)nasıl çıkarılır ?
Patryk

36

C ++ 11'den önce:

Yöntem 1 =>

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

Yöntem 2 =>

 v.push_back(SomeValue);

Aşağıda C ++ 11'den itibaren de mümkündür

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

28

İle başlayan:

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

C ++ 11 derleyiciniz yoksa ve boost kullanmak istemiyorsanız:

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

Bir C ++ 11 derleyiciniz yoksa ve boost kullanabilirsiniz:

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

Bir C ++ 11 derleyiciniz varsa:

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

22

Vektör başlatma için -

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

c ++ 11 derleyiciniz varsa yapılabilir.

Aksi takdirde, bir dizi veriye sahip olabilir ve sonra for döngüsü kullanabilirsiniz.

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

Bunların dışında, bazı kodlar kullanılarak yukarıda açıklanan çeşitli yollar vardır. Bence, bu yollar hatırlanması kolay ve hızlı yazılıyor.



16

Kullanarak kendi çözümümü oluşturuyorum va_arg. Bu çözüm C ++ 98 uyumludur.

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

gösteri


14

Derleyiciniz Variadic makrolarını destekliyorsa (çoğu modern derleyici için doğrudur), vektör başlatmayı tek katmanlı hale getirmek için aşağıdaki makroyu kullanabilirsiniz:

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

Bu makro ile aşağıdaki gibi bir kodla başlatılmış bir vektör tanımlayabilirsiniz:

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

Bu, 1, 2, 3, 4 öğeleriyle my_vector adlı yeni bir ints vektörü oluşturacaktır.


13

Boost kullanmak istemiyorsanız, ancak sözdiziminin tadını çıkarmak istiyorsanız

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

sadece bu kod yığınını dahil et

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
Bu kodu nasıl kullanacağımı anlayamadım, ama ilginç görünüyor.
Daniel Buckmaster

Yukarıdaki yorumlardan biri gibi dedi. Sadece aşırı yükleme + = ve virgül operatörü. Netlik için parantez koyma ((((v+=1),2),3),4),5) : Şu şekilde çalışır: İlk olarak, vector<T> += Tbir vector_inserter döndürür vi, orijinal vektörü çevreleyen aramaya izin verir , daha sonra tekrar yapabilmemiz için çevreleyen ve kendini döndüren vi,Torijinal vektöre T ekler . vivi,T
Piti Ongmongkolkul

Bu kod gcc 4.2.1 üzerinde düzgün çalışmadı çünkü + = operatör içinde yerel bir değişkene başvuru dönen nedeniyle düşünüyorum ama fikir exellent olduğunu. i kodu düzenledi ve bir kopya daha yapıcı görünür. akış şimdi -> + = -> ctor -> virgül -> kopya -> dtor -> virgül ...... -> virgül -> dtor.
Yevhen

Muhtemelen + = yerine << aşırı yüklenmiş olurdu. En azından << zaten bit kaymaları ve cout nedeniyle belirsiz yan etki kurallarına sahip
Speed8ump

11

C ++ 11'de:

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

21
C ++ 11'i zaten kullanıyorsanız, doğrudan yaklaşıma da gidebilirsiniz - vector<int> arr = {10, 20, 30};.
Bernhard Barker

Aslında gelen bir int [] (bazı C lib) vardı ve bir vektör (C ++ lib) içine itmek istedim. Bu cevap yardımcı oldu, gerisi olmadı ;-)
Nebula

10

bunu boost :: assign kullanarak yapabilirsiniz.

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

detay burada


19
Operatörün uzun süredir kötüye kullanımı aşırı yüklemesi gibi daha kötü bir durum görmedim. Does +=1,2,3,4 üzerine orada tack değerlerine sonuna .. ya öyle eklemek MATLAB- bu gerektiği gibi sözdizimi olarak (3 elemana 2 elemana, 3'e 1 eleman, 2 ila 1 gibi diller)
bobobobo

10

Daha yeni bir yinelenen soru vardır bu cevabı ile Viktor Sehr . Benim için kompakt, görsel olarak çekici (değerleri 'itiyorsunuz' gibi görünüyor), c ++ 11 veya üçüncü taraf modülü gerektirmiyor ve ekstra (yazılı) bir değişken kullanmaktan kaçınıyor. Aşağıda birkaç değişiklikle nasıl kullanıyorum. Gelecekteki inteadde vektör ve / veya va_arg işlevini genişletmeye geçebilirim.


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

Aşağıdaki yöntemler v ++ 'da vektör başlatmak için kullanılabilir.

  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); ve bunun gibi

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

Üçüncüsüne sadece C ++ 11'den itibaren izin verilir.


5

Burada birçok iyi cevap var, ama bunu okumadan önce bağımsız olarak kendi başıma geldiğim için, yine de benimkini buraya atacağım ...

İşte bunun için derleyiciler ve platformlarda evrensel olarak çalışacak bir yöntem kullanıyorum:

Nesneleri toplamanız için kapsayıcı olarak bir yapı veya sınıf oluşturun. << için bir operatör aşırı yük fonksiyonu tanımlayın.

class MyObject;

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

Yapınızı parametre olarak alan işlevler oluşturabilirsiniz, örneğin:

someFunc( MyObjectList &objects );

Ardından, bu işlevi şöyle çağırabilirsiniz:

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

Bu şekilde, dinamik olarak boyutlandırılmış bir nesne koleksiyonu oluşturabilir ve tek bir temiz satırda bir işleve geçirebilirsiniz!


4

Boost bağımlılığı oluşturmadan Boost :: atama ile aynı genel siparişte bir şey istiyorsanız, aşağıdakiler en azından belirsiz bir şekilde benzerdir:

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

Ben kullanmak için sözdizimi daha temiz olsaydı, yine de özellikle korkunç değil:

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

Kullanımı derlemek için:

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

Soru durumları C ++ 03 (11 değil)
Mike P

1
Bunu cevapladığımda 03 belirtmediğini düşünüyorum. Yine de mükemmel hatırlamıyorum. Ancak, hızlı bir çözüm arayan biri için hala yararlı bir cevaptır.
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

Dizi şuysa:

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

Test yazarken değişken tanımlamaksızın bir vektör satır içi oluşturmak oldukça uygundur, örneğin:

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

3

İlgili olarak, bir vektörün hızlı bir ifadeye gitmeye tamamen hazır olmasını istiyorsanız aşağıdakileri kullanabilirsiniz (örn. Hemen başka bir işleve geçme):

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

örnek işlev

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

örnek kullanım

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

decltype konusunda dikkatli olun, ancak ilk değerin açıkça istediğiniz şey olduğundan emin olun.


3

Bir vektörü sabit kodlamanın çeşitli yolları vardır, birkaç yolu paylaşacağım:

  1. Değerleri birer birer iterek başlatma
// Create an empty vector 
    vector<int> vect;  

    vect.push_back(10); 
    vect.push_back(20); 
    vect.push_back(30); 
  1. Diziler gibi başlatma
vector<int> vect{ 10, 20, 30 };
  1. Bir diziden başlatılıyor
    int arr[] = { 10, 20, 30 }; 
    int n = sizeof(arr) / sizeof(arr[0]); 

    vector<int> vect(arr, arr + n); 
  1. Başka bir vektörden başlatma
    vector<int> vect1{ 10, 20, 30 }; 

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

2

"Bir STL vektörünü nasıl oluşturabilirim ve yukarıdaki gibi başlatırım? Minimum yazma çabasıyla bunu yapmanın en iyi yolu nedir?"

Yerleşik dizinizi başlatırken bir vektörü başlatmanın en kolay yolu , C ++ 11'de tanıtılan bir başlatıcı listesi kullanmaktır .

// 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, Atama (etiketli ifade) yürütüldükten sonra boyut olarak 3 öğedir.


Benzer satırlarda, haritayı başlatmaya çalışıyorum, std :: map <int, bool> catinfo = {{1, false}}; Ama sonra bu hata hatasını alın: C ++ 98'de 'catinfo', '{...}' tarafından değil, yapıcı tarafından başlatılmalıdır
pdk

2

B. Stroustrup , Prog. C ++ 11 sürümünde 16.2.10 Selfreference sayfa 464'teki işlemleri zincirlemenin güzel bir yolunu tanımlar . Lang. burada bir fonksiyon, burada bir vektörle değiştirilen bir referans döndürür. Bu şekilde zincirleme yapabilirsiniz, v.pb(1).pb(2).pb(3);ancak bu kadar küçük kazançlar için çok fazla iş olabilir.

#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


Armadillo kütüphanesi bunu matris başlatma için yapar, ancak adlandırılmış işlev yerine << işlecini kullanır: arma.sourceforge.net/docs.html#element_initialisation
Agnel Kurian

0

En basit, daha ergonomik yol (C ++ 11 veya üstü ile):

auto my_ints = {1,2,3};

0

Kendi sınıfınızda olmasını istiyorsanız:

#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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.