这实际上是不明确的吗?

Jon*_*Mee 5 c++ nested initializer-list ambiguous list-initialization

所以我知道代码中的大括号不仅仅意味着initializer_list:如果不是intializer_list,那么什么是Curly-Brace封闭列表?

但他们应该默认什么?

例如,假设我定义了一个重载函数:

void foo(const initializer_list<int>& row_vector) { cout << size(row_vector) << "x1 - FIRST\n"; }
void foo(const initializer_list<initializer_list<int>>& matrix) { cout << size(matrix) << 'x' << size(*begin(matrix)) << " - SECOND\n"; }
Run Code Online (Sandbox Code Playgroud)

如果我打电话foo({ 1, 2, 3 })第一个显然会被调用.如果我打电话foo({ { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } })第二人显然会被召唤.

但如果我打电话怎么办:

foo({ { 1 }, { 2 }, { 3 } })
Run Code Online (Sandbox Code Playgroud)

那些嵌套的括号int- initializer_list<int>初始化器还是初始化器?gcc说这是不明确的但如果你把这些代码运行在http://webcompiler.cloudapp.net/上, Visual Studio说它只是构建一个initializer_list<int>.谁是对的?这里应该有违约吗?

Bar*_*rry 6

规则在[over.ics.list]中:

否则,如果参数类型是std::initializer_list<X>并且初始化列表的所有元素都可以隐式转换为X,则隐式转换序列是将列表元素转换为必需的最差转换X,或者如果初始化列表没有元素,则为转换.

在两个重载中,最糟糕的转换是身份转换.所以我们有两个带有秩同一性的隐式转换序列.[over.match.best]中有一条规则,它更喜欢列表初始化的std::initializer_list<X>替代选项(因此std::initializer_list<int>优先int选择{1}),但没有任何迹象表明此规则应该递归应用.

由于没有什么可以消除两个转换序列的歧义,因此调用是模糊的.gcc和clang是正确的拒绝.