GSi*_*GSi 13 c++ initializer-list overload-resolution c++11
我的问题涉及这个非常简单和简短的代码,其中在接受数组引用参数的两个非模板函数之间尝试重载解析.该问题已在其他地方发布,但在模板演绎上下文中.这是代码:
#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});
}
Run Code Online (Sandbox Code Playgroud)
g ++ 4.8.3编译这段代码选择第一个函数(我想)只有可行,而clang 3.4不编译它,说对foo的调用是不明确的(为什么?).
哪个编译器做对了?
clang甚至不会编译代码,甚至删除第二个重载:似乎初始化数组引用似乎不接受initializer_list.
这辆车有问题吗?
小智 6
我认为虽然GCC的行为更有用,但它的行为对C++ 11来说是正确的:
13.3.3.1.5列表初始化序列[over.ics.list]
2如果参数类型为
std::initializer_list<X>或"数组X"并且初始化列表的所有元素都可以隐式转换为X,则隐式转换序列是将列表元素转换为的最差转换X.
此转换序列不关注数组长度.两个函数重载都提供了一个隐式转换序列,它是一个标识转换:都引用了一个数组int,并且函数参数中的每个元素都是一个int.
然后,重载决策会看到两个身份转换,虽然标准确实有一些例外可以解决相同等级转换的冲突,但没有一个能够关注数组的长度:
13.3.3.2对隐式转换序列进行排序[over.ics.rank]
3相同形式的两个隐式转换序列是无法区分的转换序列,除非以下规则之一适用:
然后是一个根本没有提到数组的列表.
Jonathan Wakely指出,此后发生了变化.您的问题正是促使该更改的原因,相应的DR是#1307.在C++ 14中,您的代码是有效的,但在C++ 11中却没有.
| 归档时间: |
|
| 查看次数: |
357 次 |
| 最近记录: |