因此,我知道代码中的花括号不仅仅意味着一个initializer_list
:如果不是intializer_list,那么花括号括起来的列表又是什么?
但是他们应该默认为什么?
例如,假设我定义了一个重载函数:
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"; }
如果我打电话foo({ 1, 2, 3 })
给第一名,显然会被打电话给我。如果我打电话foo({ { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } })
给第二名,显然会被打电话给我。
但是,如果我打电话给我怎么办:
foo({ { 1 }, { 2 }, { 3 } })
是那些嵌套的花括号int
-initializer_list<int>
初始化程序还是初始化程序?gcc说这是模棱两可的,但是如果您采用该代码并在http://webcompiler.cloudapp.net/上运行,Visual Studio则说它只是在构建一个initializer_list<int>
。谁是对的?这里应该有默认值吗?
该规则位于[over.ics.list]中:
否则,如果参数类型为,
std::initializer_list<X>
并且初始化列表的所有元素都可以隐式转换为X
,则隐式转换序列是将列表的元素转换为所需的最差转换X
,或者如果初始化列表没有元素,则标识转换。
在这两个重载中,最糟糕的转换是身份转换。因此,我们有两个具有等级标识的隐式转换序列。[over.match.best]中有一个规则,它首选对std::initializer_list<X>
over替代项进行列表初始化(因此std::initializer_list<int>
,首选int
于{1}
),但没有建议该规则应递归应用的规则。
由于没有什么可以消除两个转换序列的歧义,因此该调用是模棱两可的。gcc和clang是正确的拒绝。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句