当我试图编译以下代码时,编译器会抱怨:
int main(void)
{
std::initializer_list<int> lst1{};
std::initializer_list<int> lst2{lst1}; // error
}
编译器(gcc(给了我以下错误:
error: could not convert '{lst1}' from '<brace-enclosed initializer list>' to 'std::initializer_list<int>'
但当我尝试使用直接初始化时,程序会编译fines:
std::initializer_list<int> lst2(lst1); // OK
为什么这是一个良好的形式?为什么编译器拒绝列表初始化并允许直接初始化?标准对此有规定吗?
Aslo,下面的代码格式正确吗?我的意思是,我能这样做吗:
int main(void)
{
std::initializer_list<int> lst1{};
std::initializer_list<std::initializer_list<int>> lst2{lst1}; //OK
}
不能从同一类型列表初始化std::initializer_list<int>
的原因是std::initializer_list<E>
的列表初始化有一个特殊规则,它优先于其他列表初始化规则。规则是[dcl.init.list]/3.6:
否则,如果
T
是std::initializer_list<E>
的特殊化,则对象将按如下所述构造。
"下面的";只能引用[dcl.init.list]/5(和/6(:
std::initializer_list<E>
类型的对象是从初始化器列表构建的,就好像实现生成并物化了([conv.rval](类型为"的prvalue;NCCD_ 6的阵列";,其中N是初始值设定项列表中的元素数。该数组的每个元素都是用初始化器列表的相应元素进行复制初始化的,并且std::initializer_list<E>
对象被构造为引用该数组。[…]
这意味着当列表初始化std::initializer_list<E>
时,对这种初始化的唯一可能解释是,支持的初始化列表的元素用于初始化std::initialize_list<E>
对象的元素。即使这是错误的格式,编译器也不能返回并尝试下一个规则,即使它可能是正确的格式(,即,[dcl.init.list]/3.7,它可以选择一个复制构造函数(。
[dcl.init.list]/5还控制您询问的其他初始化的含义:
std::initializer_list<std::initializer_list<int>> lst2{lst1};
它的形式很好,意义很明显。