2013-03-03 79 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