C ++ 11
该程序初始化vector
myVec
int
,vector
vector
,然后使用循环打印每个内部g++ 4.8.0
的{{1}}元素。但是当我试图看到当我使用额外的花括号时会发生什么,我得到了意想不到的结果。以下内容也在this LiveWorkSpace上,以便在编译器之间轻松切换。 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]
:
得到预期的输出。
{{}}
:int
:
这是0
int
的向量。内部大括号将0
初始化为myVec[3]
。
{ {}, {} }
:int
:
两个内括号将每个0
初始化为myVec[4]
。
{ {}, {}, {} }
:int
:
三个内括号将每个0
初始化为myVec[5]
。
{{{}}}
:myVec[2]
:
我想在0
添加另一组花括号,看看在获得编译错误之前我可以添加大括号。我不明白为什么这会编译以及为什么它的元素打印为int j = {}
。
例如,j
将0
初始化为vector<vector<int>> v = { {{}} }
。 {}
将最里面的int
初始化为0
vector<vector<int>> v = { {0} }
,使其等同于vector<vector<int>> u = { {{{}}} }
。那么,myVec[6]
是什么以及它为什么要编译?
假设{ {{}}, {{}} }
:myVec[7]
:
按照与上面相同的模式,我想制作一个包含两组双花括号的矢量。但这不会编译,我不明白为什么这会打破给我多个零的模式。
假设{{{{}}}}
:myVec[5]
:
我想在myVec[8]
添加另一组花括号,看看在获得编译错误之前我可以添加大括号。我不明白为什么这会破坏模式并且不会编译。
假设{ {{{}}}, {{{}}} }
:myVec[7]
:
我想扩展myVec[5]
以制作带有两组三重括号的向量。我不明白为什么这也不编译。
如果{{1}}之前的所有内容都汇编了,为什么不进行其他编译?
答案 0 :(得分:4)
尝试编译此代码。它应该解释你的问题:
int i = {}; // initializes i to int()
int j = {{}}; // fails to compile
为什么{{{}}}
在您的代码中被接受似乎是一个gcc错误(需要澄清)与ctor的处理方式有关:
struct foo {
foo( std::initializer_list<int> ) {}
};
void f()
{
foo bar1( {{{}}} ); // compiles fine
foo bar2 = {{{}}}; // compiles fine
}
编辑(感谢Johannes Schaub) - 删除副本ctor使第一个变体无法编译:
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::initializer_list<int> l = {{{}}}; // fails to compile
相同情况ctor vs std :: vector的成员函数:
void f()
{
std::vector<int> v( {{{}}} ) // compiles fine;
v.assign( {{{}}} ); // fails to compile
};
gcc 4.7.2版(Ubuntu / Linaro 4.7.2-2ubuntu1)