c++ Initializer_list作为非模板上下文中数组引用参数的参数

我的问题涉及这个非常简单和简短的代码,其中在接受数组参考参数的两个非模板函数之间尝试重载分辨率.这个问题已经在其他地方发布,但是在一个模板扣除上下文中.以下是代码:

#include <iostream>

void foo ( const int (&x) [3] ) { std::cout << "3\n"; }
void foo ( const int (&x) [2] ) { std::cout << "2\n"; }

int main()
{
    foo({1,2,3});
}

g 4.8.3编译这个代码选择第一个函数(我想)只有可行的,
而clang 3.4没有编译它,说对foo的调用是不明确的(为什么?).

哪个编译器做正确的事情?

clang不会编译代码,甚至删除第二个重载:似乎initializer_list根本不被接受来初始化数组引用.

这个小孩子吗

我认为,虽然GCC的行为更有用,但是Clang的行为对C11来说是正确的:

13.3.3.1.5 List-initialization sequence [over.ics.list]

2 If the parameter type is std::initializer_list<X> or “array of X” and all the elements of the initializer list can be implicitly converted to X, the implicit conversion sequence is the worst conversion necessary to convert an element of the list to X.

该转换序列不重视阵列长度.两个函数重载给出了一个隐式转换序列,它是一个标识转换:两者都引用一个int数组,并且函数参数中的每个元素都是一个int.

过载解决方案然后看到两个身份转换,虽然该标准确实有一些例外来解决等级转换的冲突,但是没有人注意到数组的长度:

13.3.3.2 Ranking implicit conversion sequences [over.ics.rank]

3 Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules applies:

其次是一个不提到数组的列表.

Jonathan Wakely指出,这已经改变了.你的问题是什么提示改变,相应的DR是#1307.在C 14,你的代码是有效的,但不是在C 11.

翻译自:https://stackoverflow.com/questions/27397701/initializer-list-as-argument-to-an-array-reference-parameter-in-a-not-template-c

转载注明原文:c++ Initializer_list作为非模板上下文中数组引用参数的参数