2013-03-03 54 views
11

C++ 11對整數的向量的向量統一初始化

程序初始化vector,命名myVec,的intvector s,然後使用循環來打印出每個內vector的元件。但是當我嘗試使用額外的花括號時,看到會發生什麼,我得到了意想不到的結果。編譯器之間的輕鬆切換也適用於this LiveWorkSpaceg++ 4.8.0只能彙編到myVec[5]clang++ 3.2編譯一切:

#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; 
} 

實際g++ 4.8.0輸出:

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

分析:

myVec[0]{1, 2}

得到了預期的輸出。

myVec[1]{}

得到預期的輸出。

myVec[2]{{}}

這是的int0的載體。內部大括號將int初始化爲0

myVec[3]{ {}, {} }

兩個內括號初始化每一個int0

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

三個內括號初始化每一個int0

myVec[5]{{{}}}

我想另一組花括號添加到myVec[2],看看我能走多遠有很多編譯器錯誤之前,加入括號去。我不明白爲什麼這個編譯和爲什麼它的元素打印爲0

例如,int j = {}j初始化爲0vector<vector<int>> v = { {{}} }將最內層的{}初始化爲int0,使其相當於vector<vector<int>> v = { {0} }。那麼,vector<vector<int>> u = { {{{}}} }是什麼,爲什麼要編譯?

假設myVec[6]{ {{}}, {{}} }

千篇一律如上所述,我想創建包含兩組雙大括號的載體。但是這並沒有編譯,我不明白爲什麼這打破了給我多重零的模式。

假設myVec[7]{{{{}}}}

我想另一組花括號添加到myVec[5],看看我能走多遠有很多編譯器錯誤之前,加入括號去。我不明白爲什麼這打破了模式,並沒有編譯。

假設myVec[8]{ {{{}}}, {{{}}} }

我想延長myVec[7]來使一個矢量兩套三重括號。我不明白爲什麼這不能編譯。

如果一切都達到myVec[5]編譯,爲什麼不休息?

+0

對於'{{},{}}'的情況,將內部'{}'作爲'int'的初始值設定項,在那裏調用它們的默認構造函數,給它們一個值爲'0 '。至於'{{{}}}',我不知道。 – Xymostech 2013-03-03 05:22:30

+1

[與clang,每一行都會編譯,儘管有警告。](http://liveworkspace.org/code/2VasjA$0) – Mankarse 2013-03-03 05:39:42

+0

@Mankarse do [1] - [4]警告或者僅僅是[5] - [8]? – 2013-03-03 05:46:33

回答

4

嘗試編譯該代碼。這裏需要解釋一下你的問題:

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

爲什麼{{{}}}在你的代碼被接受,似乎是一個gcc的bug(需要澄清)相關的構造函數是如何處理:

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

編輯(感謝約翰內斯·紹布) - 刪除拷貝構造函數使得第一變體的不可編譯:

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? 
} 

成員函數失敗:

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

此代碼失敗,以及:

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

相同的情況構造函數VS爲標準::向量成員函數:

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

gcc版本4.7.2(Ubuntu的/ Linaro的4.7.2- 2ubuntu1)

+0

我不是OP,但第二個不能編譯給我(看起來應該不是這樣),這似乎不能解釋爲什麼'{{{}}}'可以初始化一個'vector '在他的[5]案件中。 – 2013-03-03 05:27:54

+0

無論我放置了多少個大括號,我的編譯器只是給了我一個警告。 – Xymostech 2013-03-03 05:28:54

+0

(海灣合作委員會4.7.2在這裏,他[5]的情況下編譯我,但'int j = {{}}'不) – 2013-03-03 05:29:30