2017-02-06 11 views
7
#include <vector> 
struct S { int x; }; 
std::vector<S> v; 
int main() { v.resize(1000); return v[42].x; } 

yukarıdaki program C++ 14 0 döndürür garantisi var mı? Niye ya?İlkel tür içeren yapı kabı, sıfır başlatıldı?

+0

Olası yinelenen [Bir sınıftaki tüm çiftlerin sıfıra sıfırlanması] (http://stackoverflow.com/questions/42010793/initializing-all-doubles-in-a-class-to-zero) – SU3

cevap

3

std::vector::resize ve benzeri yöntemler sırayla agrega üyelerini değer başlatır † varsayılan tarafından değer başlatma gerçekleştirmek Evet, çünkü: cppr:

değer başlatma etkileri

itibaren

şunlardır:
[...] T varsayılan bir kurucu ile sınıf türüyse
ne kullanıcı tarafından sağlanan yani, bir örtülü tanımlanmış veya defaulte bir sınıf olabilir (ne de silindi d varsayılan yapıcı), nesne sıfır başlatılır ve daha sonra varsayılan başlangıç ​​durumuna bu önemsiz olmayan bir varsayılan kurucu sahipse olduğu;

ve Zero Initialiation kısım ihtiyacımız olan şey yapar:

T bir sendikasız sınıf tipidir, tüm baz sınıfları ve statik olmayan veri üyeleri sıfır başlangıç ​​durumuna getirilir ve tüm dolgu başlatılır sıfır biti. Varsa, yapıcılar göz ardı edilir.

Ve tabii ki, bizim üyesinin sıfır başlatma doğru olanı yapar:

T sayıl tipi ise, nesnenin başlangıç ​​değeri açıkça

T.

dönüştürülen ayrılmaz sabit sıfırdır

† varsayılan ayırıcısı, özel ayırıcılarına farklı başlatma kullanabilir gelmez. Sen, unitialized tür değerleri terk için kullanıyoruz default-insert tam makaleyi görebilirsiniz.

3

yukarıdaki program C++ 14 0 döndürür garantisi var mı? Niye ya?

Evet. [Vector.capacity] kaynaktan:

void resize(size_type sz);
13 Effects: sz < size() durumunda, dizinin son size() - sz elemanları siler. Aksi takdirde, diziye sz - size()varsayılan eklenen elemanları ekler.

durumlarda, [container.requirements.general] 'den:

X bir elemanıdır varsayılan sokulmuş, ifade allocator_traits<A>::construct(m, p) değerlendirilmesi ile başlatıldı,p adresidir X içinde ayrılan öğe için başlatılmamış depolama.

template <class U, class... Args> 
void construct(U* p, Args&&... args); 

etkileri: std::allocator<T> için

construct [default.allocator] 'den, yapar ::new((void *)p) U(std::forward<Args>(args)...)

Yani, bu değer başlatma var. , new S değil, x üye sıfır başlatılacaktır. (Istenirse) bu davranışı kaçınarak ait


yolu ya şunlardır:

  1. Değişim ayırıcısı. construct için iki aşırı yüklenmeye sahip kendi ayırıcı türünüzü sağlayın: biri boş (varsayılan başlatma) ve bir tanesi Args&&....
  2. Türünü değiştirin. Hiçbir başlangıç ​​yapmaz S için bir varsayılan kurucu ekleyin.
İlgili konular