2013-03-03 26 views
11

C++ 11Düzgün başlatma

programı intvector s, myVec adlı bir vector başlatır, ve daha sonra her bir iç vector sitesindeki elemanları yazdırmak için bir döngü kullanır . Fakat ekstra kıvırcık parantez kullandığımda ne olduğunu görmeye çalışırken beklenmedik sonuçlar elde ettim. Derleyiciler arasında kolay geçiş için aşağıdaki this LiveWorkSpace da bulunmaktadır. g++ 4.8.0 yalnızca myVec[5]'a kadar derler. clang++ 3.2 derler herşey:

#include <iostream> 
#include <vector> 

int main() 
{ 
    std::vector<std::vector<int>> myVec = 
    { 
     /* myVec[0] */ {1, 2}, 
     /* myVec[1] */ {}, 
     /* myVec[2] */ {{}}, 
     /* myVec[3] */ { {}, {} }, 
     /* myVec[4] */ { {}, {}, {} }, 
     /* myVec[5] */ {{{}}} 

     /* myVec[6] */ // , { {{}}, {{}} }  // g++ 4.8.0 COMPILER ERROR 
     /* myVec[7] */ // , {{{{}}}}    // g++ 4.8.0 COMPILER ERROR 
     /* myVec[8] */ // , { {{{}}}, {{{}}} } // g++ 4.8.0 COMPILER ERROR 
    }; 

    // loop for printing 
    for (unsigned int i = 0; i < myVec.size(); ++i) 
    { 
     std::cout << "myVec[" << i << "]: "; 
     for (unsigned int j = 0; j < myVec.at(i).size(); ++j) 
     { 
      std::cout << myVec.at(i).at(j) << ", "; 
     } 
     std::cout << std::endl; 
    } 
    return 0; 
} 

Fiili g++ 4.8.0 çıkışı:

myVec[0]: 1, 2, 
myVec[1]: 
myVec[2]: 0, 
myVec[3]: 0, 0, 
myVec[4]: 0, 0, 0, 
myVec[5]: 0, 

Analiz:

myVec[0]: {1, 2}:

Beklediğiniz çıktı var.

myVec[1]: {}:

çıkış bekleniyor var.

myVec[2]: {{}}:

Bu int0 bir vektördür. İç destek, int'u 0'a başlatır.

myVec[3]: { {}, {} }:

iki iç parantez 0 bir int her başlatır.

myVec[4]: { {}, {}, {} }:

üç iç parantez 0 bir int her başlatır.

myVec[5]: {{{}}}:

Ben derleyici hatalarını almadan önce parantez ekleyerek ne kadar ileri gidebileceğimizi görmek myVec[2] henüz küme parantezleri başka bir set eklemek istedim. Bunun neden derlendiğini ve elemanının neden 0 olarak yazdırıldığını anlamıyorum.

Örneğin, int j = {}0 için j başlatır. vector<vector<int>> v = { {{}} }, en {} değerini int0 için vector<vector<int>> v = { {0} } eşdeğerine dönüştürür. O zaman, vector<vector<int>> u = { {{{}}} } nedir ve neden derlenmelidir?

Varsayımsal myVec[6]: { {{}}, {{}} }: Yukarıdaki aynı desen ardından

, ben çift küme parantezleri iki set içeren bir vektör yapmak istedi. Ama bu bir derleme yapmıyor, ve neden bunun bana birden fazla sıfır veren modelini kırdığını anlamıyorum.

Varsayımsal myVec[7]: {{{{}}}}:

Ben derleyici hatalarını almadan önce parantez ekleyerek ne kadar ileri gidebileceğimizi görmek myVec[5] henüz küme parantezleri başka bir set eklemek istedim. Bunun neden desen kırdığını ve neden derlenmediğini anlamıyorum.

Varsayımsal myVec[8]: { {{{}}}, {{{}}} }:

Üçlü parantez iki takım ile bir vektör yapmaya myVec[7] uzatmak istedi. Bunun neden böyle olmadığını anlamıyorum.

myVec[5] derlerken için her şey, neden gerisini Değilse?

+0

'{{}, {}}' durumda, onları '0 değerini vererek varsayılan yapıcı olarak adlandırılır' int's içindir, bu başlatıcıları I '} {' iç düşünmek '. '{{{}}}' Ile ilgili olarak, hiçbir fikrim yok. – Xymostech

+1

[. Clang ile her hat uyarılar ile de olsa, derler] (http://liveworkspace.org/code/2VasjA$0) – Mankarse

+0

yapmak @Mankarse [1] - [4] uyarmak veya [5] - [8]? –

cevap

4

bu kodu derlemek için deneyin. o sorunu açıklamalıdır:

struct foo { 
    foo(std::initializer_list<int>) {} 
}; 
void f() 
{ 
    foo bar1({{{}}}); // compiles fine 
    foo bar2 = {{{}}}; // compiles fine 
} 

Düzenleme (teşekkür Johannes Schaub için: {{{}}} kodunuzda kabul edilir neden gcc hata olması

int i = {}; // initializes i to int() 
int j = {{}}; // fails to compile 

görünüyor ctor nasıl işleneceğini ilgili (netleştirmek gerekiyor) -) kopya ctor silme birinci varyant derlenemez yapar:

struct foo { 
    foo(std::initializer_list<int>) {} 
    foo(const foo&) = delete; 
}; 
void f() 
{ 
    foo bar1({{{}}}); // fails to compile: use of deleted function ‘foo::foo(const foo&)’ 
    foo bar2 = {{{}}}; // still compiles, neither deleting move ctor, nor assignment operator does not affect that, is copy ctor of std::initializer_list involved? 
} 

üye işlev için başarısız:

struct foo { 
    void moo(std::initializer_list<int>) {} 
}; 
void f() 
{ 
    foo bar; 
    bar.moo({{{}}}); // fails to compile 
} 

Bu kod yanı başarısız:

std::initailizer_list<int> l = {{{}}}; // fails to compile 

std :: vektörü için üye fonksiyonu vs Aynı durum ctor:

void f() 
{ 
    std::vector<int> v({{{}}}) // compiles fine; 
    v.assign({{{}}}); // fails to compile 
}; 

gcc sürüm 4.7.2 (Ubuntu/Linaro 4.7.2- için 2ubuntu1)

+0

OP değilim, ancak ikincisi benim için derleme yapmıyor (görünmesi gerektiği gibi görünmüyor), bu da niçin '{{{}}} 'bir vektörü ' başlatabildiğini açıklamıyor gibi görünmüyor [5] durumunda. –

+0

Derleyicim, kaç tane parantez biriktirdiğime bakılmaksızın bana bir uyarı veriyor. – Xymostech

+0

(gcc 4.7.2 burada, onun [5] davası benim için derler ama int int = {{}} 'değil) –