std :: dynarray vs std :: vektör


84

C ++ 14 sunar std::dynarray:

std :: dynarray, dizileri yapım aşamasında sabit olan ve nesnenin ömrü boyunca değişmeyen bir boyutta kapsülleyen bir sıra kapsayıcısıdır.

std::dynarrayile aynı şekilde çalışma zamanında tahsis edilmelidir std::vector.

Öyleyse daha dinamik (ve aynı zamanda yeniden boyutlandırılabilir) std::dynarraykullanabildiğimiz zamanın faydaları ve kullanımı std::vectornelerdir?


1
Hey, "C ++ 14" ne zamandan beri etiket oluyor? Geçen gün onu arıyordum ve yoktu ...
Kerrek SB

1
std::valarrayOlarak yeniden adlandırıldı mı std::dynarray? Ne std::dynarrayzaman yeniden boyutlandırılamayacağı konusunda dinamik olan nedir?
yasouser

9
@yasouser, hayır, bununla alakası yok valarray. Dinamiktir çünkü dizinin uzunluğu bir çalışma zamanı değeridir, aksine, derleme zamanında bilinmesi gerekmezstd::array
Jonathan Wakely 13

21
Geçen hafta C ++ Standartlar Komitesi toplantısında dynarray, C ++ 14'ten çıkarıldığını ve gelecekteki bir Teknik Şartnameye konduğunu (bunu TR1'in yeni bir sürümü olarak düşünün) çünkü bazı ciddi teknik sorunları olduğunu unutmayın.
Pete Becker

2
dynarray artık C ++ 14 taslağının bir parçası değil
cassinaj

Yanıtlar:


90

Peki daha dinamik olanı (Yeniden boyutlandırılabilir) std::dynarrayne zaman kullanabiliriz std::vector?

dynarraydaha küçük ve daha basittir vector, çünkü ayrı boyut ve kapasite değerlerini yönetmesi gerekmez ve bir ayırıcı depolaması gerekmez.

Bununla birlikte, ana performans faydasının, dynarrayherhangi bir yığın tahsisinden kaçınarak, uygulamaların mümkün olduğunda yığın üzerinde tahsis etmeye teşvik edilmesinden kaynaklanması amaçlanmaktadır . Örneğin

std::dynarray<int> d(5);   // can use stack memory for elements
auto p = new std::dynarray<int>(6);  // must use heap memory for elements

Bu optimizasyon, derleyiciden işbirliği gerektirir, saf bir kitaplık türü olarak uygulanamaz ve gerekli derleyici sihri uygulanmamıştır ve kimse bunun ne kadar kolay olduğundan emin değildir. Uygulama deneyiminin olmaması nedeniyle, geçen hafta Chicago'daki C ++ komite toplantısında std::dynarray, C ++ 14'ten çekilmesine ve ayrı bir dizi uzantıları TS (teknik belirtim) belgesi tanımlayan std::experimental::dynarrayve çalışma zamanı sınırlarının dizilerini (ARB'ler, benzer C99 VLA'lara.) Bu std::dynarray, neredeyse kesinlikle C ++ 14'te olmayacağı anlamına gelir .


1
Olsaydı Büyük, acaba herhangi apaçık olmayan uygulamaları dynarrayvahşi. Her zaman, bir şey standardizasyon için uygun hale gelmeden önce mevcut uygulamanın iki bağımsız uygulamasına ihtiyacınız olduğunu düşündüm.
Kerrek SB

Hayır, yığın ayırmanın bilinen uygulamaları yoktur dynarray. Uygulama deneyimi çok faydalı olsa da, bunu gerektiren belirli bir kural yoktur (ancak bazıları olması gerektiğini söyler!)
Jonathan Wakely

burada sadece beyin fırtınası yapıyorum ama peki ya 2 işlev yaratmaya ne dersiniz: std :: dynarray make_dyn_autostorage (int) ve std :: dynarray make_dyn_heap (int)?
Laurijssen

2
@KerrekSB, evet, Chicago'daki kütüphane hareketi 10 şöyleydi: "Planlanmış bir Dizi Uzantıları TS için bir Çalışma Kağıdı oluşturalım, C ++ 14 CD'sine iki N3639 kağıt tarafından uygulanan düzenlemeleri kaldıralım ," Çalışma zamanı boyutunda diziler otomatik depolama süresi (revizyon 5) " N3662 ," C ++ Dynamic Arrays (dynarray) "ve Array Extensions TS proje düzenleyicisini, bu kelimeleri, başlangıç ​​içeriği olarak Array Extensions Working Paper'a uygulaması için yönlendirin."
Jonathan Wakely

3
@ h9uest, "C ++ çalışanları" ile hiçbir ilgisi yoktur, bunlar bir ISO teknik komitesinin çıktılarının resmi isimleridir , bkz. iso.org/iso/home/standards_development/… ve iso.org/iso/home/standards_development /…
Jonathan Wakely

31

Kendin söyledin, std::dynarraybir içindir sabit boyutlu dinamik dizide. Yeniden boyutlandırılamaz. Kabaca göre bir gelişme konuşuyor new T[N]ve üzeri std::unique_ptr<T[]>(new T[N]).

Kapasiteyi yeniden boyutlandırmaya veya yönetmeye gerek kalmaması, veri yapısını daha az karmaşıklıkla ve daha az alanda uygulayabileceğiniz anlamına gelir.

Dahası, std::dynarrayuygulamanın onu farklı, spesifik olmayan yollarla gerçekleştirmesine izin veren tuhaf bir hayvandır, örneğin diziyi yığına koymak mümkündür. Bir tahsis işlevinin çağrılması "isteğe bağlıdır". Dizinin öğelerini oluşturmak için bir ayırıcı belirtebilirsiniz, ancak bu, türün bir parçası değildir.

Ayrıca neden std::dynarray ve değişken uzunluklu dizilere ihtiyacımız olduğunu merak edebilirsiniz . C ++ 14'teki VLA'lar çok daha kısıtlayıcıdır; bunlar yalnızca yerel, otomatik değişkenler olabilirler ve bir ayırma politikası belirlemenin hiçbir yolunu sunmazlar ve elbette standart bir konteyner arayüzüne sahip değiller.


23.3.4.2'deki "mevcut taslağın" bazı örnekleri (bunu al, Google önbelleği):

explicit dynarray(size_type c);

Efektler:c Öğeler için depolama alanı ayırır . Global olanı çağırabilir veya çağırmayabilir operator new.

template <class Alloc>
dynarray(size_type c, const Alloc& alloc);

Etkiler: Her bir öğenin kullanım ayırıcı yapısıyla oluşturulması dışında önceki kuruculara eşdeğerdir .

Eğer olsun ya da olmasın edebilir dizi elemanlarını oluşturmak için belirli bir ayırıcısı kullandıkları küresel özelliktir:

şablon struct uses_allocator, Alloc>: true_type {};

Gereksinim: Alloc Bir Dağıtıcı (17.6.3.5) olacaktır. [ Not: Bu özelliğin uzmanlığı, dynarrayyuvalanmış bir ayırıcı türü olmasa bile bir ayırıcıyla oluşturulabilen diğer kitaplık bileşenlerini bilgilendirir .]

Düzenleme: Jonathan Wakely'nin cevabı çok daha yetkili ve anlayışlı olacaktır.


Bir ayırıcının dynarrayyapıcısına aktarılması asla ayırma için kullanılmaz, yalnızca öğelerin yapıcılarına bir argüman olarak kullanılır ("kullanım ayırıcı yapısı" kullanılarak). Bu yüzden ayırıcının kullanılıp kullanılmadığını sorgulayamazsınız: çünkü asla kullanılmaz.
Jonathan Wakely

@JonathanWakely: Ah, bunu yanlış anladım. Teşekkürler, düzeltildi!
Kerrek SB
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.