Diziyi vektöre dönüştürmenin en basit yolu nedir?


94

Diziyi vektöre dönüştürmenin en basit yolu nedir?

void test(vector<int> _array)
{
  ...
}

int x[3]={1, 2, 3};
test(x); // Syntax error.

X'i int dizisinden vektöre en basit şekilde dönüştürmek istiyorum.

Yanıtlar:


140

vectorİki yineleyici alan yapıcıyı kullanın, işaretçilerin geçerli yineleyiciler olduğunu unutmayın ve dizilerden işaretleyicilere örtük dönüştürmeyi kullanın:

int x[3] = {1, 2, 3};
std::vector<int> v(x, x + sizeof x / sizeof x[0]);
test(v);

veya

test(std::vector<int>(x, x + sizeof x / sizeof x[0]));

sizeof x / sizeof x[0]açıkça 3bu bağlamda nerede ; bir dizideki elemanların sayısını elde etmenin genel bir yoludur. Son öğenin ötesindex + sizeof x / sizeof x[0] bir öğeyi işaret ettiğine dikkat edin.


1
Lütfen açıklar mısınız? Bunun int` vector<int> a(5,10);anlamına make room for 5 geldiğini zaten okudum ve onları 10 ile başlattım. Peki x, x + ... nasıl çalışır? açıklayabilir misin?
Asif Mushtaq

1
@UnKnown seçmek yerine vector<int>::vector(size_type, int), o vector<int>::vector(int*, int*)işaretçi çifti ile gösterilen aralığı kopyalayan seçer . Birincisi aşırı yük (2), ikincisi aşırı yük (4) burada
Caleth

1
C ++ 11'de std :: reach, sizeof yönteminden daha iyidir. sizeof x / sizeof x[0] == std::extent<decltype(x)>::value
Isaac Pascual

116

Kişisel olarak, C ++ 2011 yaklaşımını çok beğeniyorum çünkü sizeof()dizi sınırlarını değiştirirseniz, dizi sınırlarını kullanmanızı veya bunu ayarlamayı hatırlamanızı gerektirmez (ve isterseniz C ++ 2003'te ilgili işlevi de tanımlayabilirsiniz. ):

#include <iterator>
#include <vector>
int x[] = { 1, 2, 3, 4, 5 };
std::vector<int> v(std::begin(x), std::end(x));

Açıkçası, C ++ 2011 ile yine de başlatıcı listelerini kullanmak isteyebilirsiniz:

std::vector<int> v({ 1, 2, 3, 4, 5 });

2
diziyi kopyalıyor mu yoksa sadece onu mu gösteriyor? performansla ilgileniyorum
kirill_igum

2
std::vector<T>her zaman Tnesnelerin sahibidir . Bunun iki sonucu vardır: bir vektöre nesne eklerken kopyalanırlar ve bellekte yan yana yerleştirilirler. Makul ölçüde küçük nesneler için, örneğin kısa dizgiler için, sıralama büyük bir performans kazancıdır. Nesneleriniz büyük ve kopyalanması pahalıysa, nesnelere [bir şekilde kaynak tarafından yönetilen] işaretçiler depolamak isteyebilirsiniz. Hangi yaklaşımın daha verimli olduğu nesnelere bağlıdır, ancak seçim hakkınız vardır.
Dietmar Kühl

Öyleyse, bir c ++ ve ac kütüphaneleri arasında arayüz oluşturmak ve c dizisinden vektöre ve geri kopyalamak istersem, 2 kopya cezasını ödemenin bir yolu yok mu? (i eigen kütüphane ve GSL kullanıyorum)
kirill_igum

16

İşaretçiler, diğer yineleyiciler gibi kullanılabilir:

int x[3] = {1, 2, 3};
std::vector<int> v(x, x + 3);
test(v)

2
Gerçek hayatta, örneğin const size_t X_SIZE = 3;dizi boyutunu belirtmek için kullanarak veya sizeof'tan hesaplayarak dizi boyutunu soyutlamak isteyebilirsiniz . Okunabilirlik uğruna bu bölümü atladım.
Rafał Rawicki

11

Burada yanlış soruyu soruyorsunuz - her şeyi bir vektöre zorlamak yerine, testi belirli bir kap yerine yineleyicilerle çalışmaya nasıl dönüştüreceğinizi sorun. Uyumluluğu korumak (ve aynı anda diğer kapsayıcıları ücretsiz olarak kullanmak) için bir aşırı yükleme de sağlayabilirsiniz:

void test(const std::vector<int>& in) {
  // Iterate over vector and do whatever
}

şu hale gelir:

template <typename Iterator>
void test(Iterator begin, const Iterator end) {
    // Iterate over range and do whatever
}

template <typename Container>
void test(const Container& in) {
    test(std::begin(in), std::end(in));
}

Bunu yapmanıza izin veren:

int x[3]={1, 2, 3};
test(x); // Now correct

( Fikir demosu )


"Her şeyi bir vektöre zorlamak yerine, testi belirli bir kap yerine yineleyicilerle çalışmaya nasıl dönüştürebileceğinizi sorun." Bu neden daha iyi?
aquirdturtle

1
@aquirdturtle çünkü artık sadece vektörleri desteklemek yerine listeleri ve dizileri destekliyor ve kapsayıcıları güçlendiriyor, yineleyicileri ve aralıkları dönüştürüyorsunuz ve ....
Flexo

2
ve verileri kopyalamanıza gerek yoktu
Orbit

2

Basit bir yol, sınıfta assign()önceden tanımlanmış işlevin kullanılması olabilir vector.

Örneğin

array[5]={1,2,3,4,5};

vector<int> v;
v.assign(array, array+5); // 5 is size of array.

2
Yaklaşık yedi yıl önce mevcut cevaplarda bahsedilen ctor kullanımına eşdeğer. Hiçbir şey
eklemez
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.