2013-05-15 12 views
8

pek çok yöntem, örneğin, value_type nesnelere bir sabit başvuru alır: bir uzman olmayan C++ programcı olarakstd :: vektörünün yeniden boyutlandırma yönteminin ardındaki tasarım mantığı nedir? şablon sınıfı <code>vector</code> içinde

void resize (size_type n, value_type val = value_type()); 

:

void push_back (const value_type& val); 

resize ise değer tarafından value_type parametre alır Sadece bu seçenekle dezavantajları düşünebilirim (örneğin, size_of(value_type) yeterince büyük yığın taşması meydana gelebilir). Dile daha fazla içgörü duyan insanlara sormak istediklerim şu şekildedir:

Bu seçimin arkasındaki tasarım mantığı nedir?

+1

@ user814628 Bu bana doğru gelmiyor. 'Value_type val = value_type()' adlı tek zaman işe yaramazsa, 'value_type', const olmayan bir referansa sahip olan bir kopya kurucusuna sahip olsaydı. –

+0

Daha önce hiç fark etmedim * yeniden * boyutlandırmak için ikinci bir parametre * (...)! Sanırım bir gün için bir şey öğrendim ve şimdi yarına kadar gidebilir. : -P – aldo

cevap

9
void resize(size_type count, T value = T()); 

Bu fonksiyon C++ 11 ile kaldırıldı.

C++ 11 resize() ait two overloads sahiptir: hemen hemen anlaşılır anlamaktır

void resize(size_type count); 
void resize(size_type count, const value_type& value); 

. Birincisi, yeniden boyutlandırırken vektörü doldurmak için value_type türünde varsayılan yapılandırılmış nesneleri kullanır, ikincisi yeniden boyutlandırılırken kopyalar yaptığı bir değeri alır.

+0

Benim hatam! Standart taslaktan ziyade [cplusplus] (http://www.cplusplus.com/reference/vector/vector/resize/) adresinden C++ 11 prototipine bakacak kadar tembel davrandım ve burada yanlış ! – Massimiliano

+5

@Massimiliano: cplusplus C++ öğreticileri için kötü bir site: hatta C++ 11 imzaları burada yanlış. Bu const ve 'eksik. ** cplusplus.com üzerinden [cppreference.com] (http://en.cppreference.com/w/cpp) tercih edin ** – Nawaz

+0

Bahşiş için teşekkürler, bunun yerine cppreference kullanmaya başlayacağım. – Massimiliano

6

Bu bir tasarım hatası gibi görünüyor, şimdi düzeltildi.

void boyutlandırma (size_type: tek kapların bir üye fonksiyonu değerle yerine const referans olarak parametre (T) geçer STL defects 679

C++ 98 standart belirtir gelen teklif

sz, Tc = T()); Bu gerçek, yıllar içinde tekrar tekrar tartışılmış/tartışılmıştır, ilk kez C++ 98'in onaylanmasından önce bile ilk kez onaylanmıştır. değeriyle bu parametreyi geçirerek gerekçesi olmuştur:

Yani ifadeleri başvuran bu kendini işine garanti edilir, örneğin: push_back için imzadır olarak

v.resize(v.size() + 1, v[0]); 

Ancak bu gerekçe inandırıcı değil:

void push_back(const T& x); 

Ve push_back yeniden boyutlandırmak için benzer semantiklere sahiptir (ekleme). Ve push_back de kendi kendine referans durumda çalışmalıdır:

v.push_back(v[0]); // must work 

değeriyle T geçirerek ile sorun referans olarak geçen önemli ölçüde daha fazla pahalı olabilir olmasıdır. Bu görüşme aynı zamanda doğrudur, ancak doğru olduğu zaman genellikle çok daha az dramatiktir (ör., Skaler tipler için).

Mevcut taşıma semantikleriyle bile, bu parametreyi değere göre iletmek pahalı olabilir.> Örneğin vektörü için göz önünde bulundurun: geçiş değer-ile-durumunda

std::vector<int> x(1000); 
std::vector<std::vector<int>> v; 
... 
v.resize(v.size()+1, x); 

x boyutlandırmak parametre için bir kez kopyalanır. Ve sonra dahili olarak, kod ne kadar yeniden boyutlandırmanın vektörü büyüttüğünü derleme zamanında bilmediği için, x, yeniden boyutlandırma parametresinden vektör içindeki doğru yerine ikinci kez kopyalanır (taşınmaz).

Teslim özniteliği referansı ile, yukarıdaki örnekte x'in yalnızca bir kez kopyalanması gerekir. Bu durumda, x pahalı bir kopya oluşturucusuna sahiptir ve böylece kaydedilebilecek herhangi bir kopya önemli bir tasarruf anlamına gelir.

Eğer push_back için verimli olabilirsek, yeniden boyutlandırma için de verimli olmalıyız. Referans parametresi alarak yeniden boyutlandırma kodlanmış ve CodeWarrior kütüphanesinde, farkında olduğum herhangi bir sorun bildirilmeden gönderilmiştir.

Önerilen çözünürlük:

değiştirme 23.3.3 [deque], p2:

class deque { 
    ... 
    void resize(size_type sz, const T& c); 

değiştirme 23.3.3.3 [deque.capacity], P3:

void resize(size_type sz, const T& c); 

değiştirme 23.3. 5 [liste], p2:

class list { 
    ... 
    void resize(size_type sz, const T& c); 

Ch ange 23.3.5.3 [list.capacity], P3:

void resize(size_type sz, const T& c); 

değiştirme 23.3.6 [vektörü], p2:

class vector { 
    ... 
    void resize(size_type sz, const T& c); 

değiştirme 23.3.6.3 [vector.capacity] p11:

void resize(size_type sz, const T& c); 
İlgili konular